from __future__ import annotations

import json
import os
import re
from pathlib import Path
from typing import Any, Dict

from common.runtime_paths import cloud_data_dir


CLOUD_DISPLAY_NAMES = {
    "huawei": "华为云",
    "ctyun": "天翼云",
    "volc": "火山云",
}

_CLOUD_ALIASES = {
    "huawei": "huawei",
    "huaweicloud": "huawei",
    "hw": "huawei",
    "ctyun": "ctyun",
    "ct": "ctyun",
    "tianyi": "ctyun",
    "volc": "volc",
    "volcengine": "volc",
    "huoshan": "volc",
}

_STANDALONE_LIMITED_ENV_NAMES = {
    "huawei": "WAWA_HUAWEI_STANDALONE_LIMITED",
    "ctyun": "WAWA_CTYUN_STANDALONE_LIMITED",
    "volc": "WAWA_VOLCENGINE_STANDALONE_LIMITED",
}
LIMITED_VENDOR_FEATURES_ENV = "WAWA_LIMITED_VENDOR_FEATURES"


def normalize_cloud_key(cloud: str) -> str:
    return _CLOUD_ALIASES.get(str(cloud or "").strip().lower(), "")


def limited_vendor_features_enabled(cloud: str) -> bool:
    cloud_key = normalize_cloud_key(cloud)
    if not cloud_key:
        return False
    raw_value = os.environ.get(LIMITED_VENDOR_FEATURES_ENV, "").strip()
    if not raw_value:
        return False
    tokens = [item for item in re.split(r"[,;|\s]+", raw_value.lower()) if item]
    if any(token in {"*", "all", "customer", "limited"} for token in tokens):
        return True
    return cloud_key in {normalize_cloud_key(token) for token in tokens}


def _standalone_limited(cloud_key: str) -> bool:
    env_name = _STANDALONE_LIMITED_ENV_NAMES.get(cloud_key, "")
    if env_name and os.environ.get(env_name, "").strip() == "1":
        return True
    # CTYUN customer-code limits are resource-management-only; do not reuse them
    # for standalone purchase/build restrictions.
    if cloud_key != "ctyun" and limited_vendor_features_enabled(cloud_key):
        return True
    return normalize_cloud_key(os.environ.get("WAWA_SINGLE_VENDOR", "")) == cloud_key


def _state_path() -> Path:
    path = cloud_data_dir("common") / "on_demand_debug.json"
    path.parent.mkdir(parents=True, exist_ok=True)
    return path


def _load_state() -> Dict[str, bool]:
    path = _state_path()
    if not path.exists():
        return {}
    try:
        raw = json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return {}
    if not isinstance(raw, dict):
        return {}
    state: Dict[str, bool] = {}
    for key, value in raw.items():
        cloud_key = normalize_cloud_key(str(key))
        if cloud_key:
            state[cloud_key] = bool(value)
    return state


def _write_state(state: Dict[str, bool]) -> None:
    safe_state = {key: bool(state.get(key)) for key in CLOUD_DISPLAY_NAMES}
    _state_path().write_text(
        json.dumps(safe_state, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )


def _env_override(cloud_key: str) -> bool | None:
    names = [
        f"WAWA_ON_DEMAND_DEBUG_{cloud_key.upper()}",
        f"WAWA_DEBUG_BILLING_{cloud_key.upper()}",
    ]
    if cloud_key == "volc":
        names.extend(["WAWA_ON_DEMAND_DEBUG_VOLCENGINE", "WAWA_DEBUG_BILLING_VOLCENGINE"])
    for name in names:
        value = os.environ.get(name)
        if value is None:
            continue
        normalized = value.strip().lower()
        if normalized in {"1", "true", "yes", "on", "enabled"}:
            return True
        if normalized in {"0", "false", "no", "off", "disabled"}:
            return False
    return None


def is_on_demand_debug_enabled(cloud: str) -> bool:
    cloud_key = normalize_cloud_key(cloud)
    if not cloud_key or _standalone_limited(cloud_key):
        return False
    override = _env_override(cloud_key)
    if override is not None:
        return override
    return bool(_load_state().get(cloud_key))


def set_on_demand_debug_enabled(cloud: str, enabled: bool) -> bool:
    cloud_key = normalize_cloud_key(cloud)
    if not cloud_key:
        return False
    state = _load_state()
    state[cloud_key] = bool(enabled) and not _standalone_limited(cloud_key)
    _write_state(state)
    return state[cloud_key]


def on_demand_debug_state() -> Dict[str, Any]:
    state = _load_state()
    return {
        key: bool(state.get(key)) and not _standalone_limited(key)
        for key in CLOUD_DISPLAY_NAMES
    }
