import os


def _load_local_env():
    path = ".env"
    if not os.path.exists(path):
        return
    try:
        with open(path, "r", encoding="utf-8") as handle:
            for raw_line in handle:
                line = raw_line.strip()
                if not line or line.startswith("#") or "=" not in line:
                    continue
                key, value = line.split("=", 1)
                key = key.strip()
                value = value.strip().strip('"').strip("'")
                if key and key not in os.environ:
                    os.environ[key] = value
    except OSError:
        return


_load_local_env()


def _env_flag(name: str, default: bool = False) -> bool:
    raw = os.getenv(name)
    if raw is None:
        return default
    return raw.strip().lower() in {"1", "true", "yes", "on"}


def _env_csv(name: str, default=None):
    raw = os.getenv(name)
    if raw is None:
        return list(default or [])
    return [item.strip() for item in raw.split(",") if item.strip()]


def _env_int(name: str, default: int) -> int:
    raw = os.getenv(name)
    if raw is None:
        return default
    try:
        return int(raw)
    except ValueError:
        return default


def _env_float(name: str, default: float) -> float:
    raw = os.getenv(name)
    if raw is None:
        return default
    try:
        return float(raw)
    except ValueError:
        return default


def _env_str(name: str, default: str) -> str:
    raw = os.getenv(name)
    if raw is None:
        return default
    return raw


ALLOW_WRAPPER_PY = _env_flag("HIVE_ALLOW_WRAPPER_PY", default=False)
WRAPPER_SPEC_ALLOWLIST = _env_csv("HIVE_WRAPPER_SPEC_ALLOWLIST", default=[])
REQUIRE_WRAPPER_SPEC_SIGNATURE = _env_flag("HIVE_REQUIRE_WRAPPER_SPEC_SIGNATURE", default=False)
WRAPPER_SPEC_SIGNING_KEY = os.getenv("HIVE_WRAPPER_SPEC_SIGNING_KEY", "")
CORS_ALLOWED_ORIGINS = _env_csv(
    "HIVE_CORS_ALLOWED_ORIGINS",
    default=["http://localhost:5173", "http://127.0.0.1:5173"],
)
CORS_SUPPORTS_CREDENTIALS = _env_flag("HIVE_CORS_SUPPORTS_CREDENTIALS", default=False)
API_HOST = os.getenv("HIVE_API_HOST", "0.0.0.0")
API_PORT = _env_int("HIVE_API_PORT", _env_int("PORT", 8080))
AI_PROVIDER = os.getenv("HIVE_AI_PROVIDER", "ollama").strip().lower()
AI_OLLAMA_MODEL = (
    os.getenv("HIVE_AI_OLLAMA_MODEL")
    or os.getenv("HIVE_AI_MODEL")
    or os.getenv("OLLAMA_MODEL")
    or "phi3"
)
AI_OLLAMA_TIMEOUT_SEC = _env_int("HIVE_AI_OLLAMA_TIMEOUT_SEC", 40)
AI_ROUTE_MODEL_DEFAULT = _env_str("HIVE_AI_ROUTE_MODEL_DEFAULT", "").strip()
AI_ROUTE_MODEL_LOCALIZE = _env_str("HIVE_AI_ROUTE_MODEL_LOCALIZE", "").strip()
AI_ROUTE_MODEL_TUTOR = _env_str("HIVE_AI_ROUTE_MODEL_TUTOR", "").strip()
AI_ROUTE_MODEL_HARDWARE_EXPLAINER = _env_str("HIVE_AI_ROUTE_MODEL_HARDWARE_EXPLAINER", "").strip()
AI_ROUTE_MODEL_INTENT_COMPILE = _env_str("HIVE_AI_ROUTE_MODEL_INTENT_COMPILE", "").strip()
_DEFAULT_TRACE_HOME = os.path.join(os.path.expanduser("~"), ".hiveos-trace")
_DEFAULT_TRACE_LOG_PATH = os.path.join(_DEFAULT_TRACE_HOME, "logs", "trace_events.log")
TRACE_LOG_PATH = _env_str("HIVE_TRACE_LOG_PATH", _DEFAULT_TRACE_LOG_PATH)
TRACE_MAX_BYTES = _env_int("HIVE_TRACE_MAX_BYTES", 5 * 1024 * 1024)
TRACE_MAX_ROTATIONS = _env_int("HIVE_TRACE_MAX_ROTATIONS", 5)
TRACE_READ_MAX_LINES = _env_int("HIVE_TRACE_READ_MAX_LINES", 200000)
TRACE_DB_ASYNC = _env_flag("HIVE_TRACE_DB_ASYNC", default=True)
TRACE_DB_QUEUE_MAX = _env_int("HIVE_TRACE_DB_QUEUE_MAX", 5000)
TRACE_SAMPLING_ENABLED = _env_flag("HIVE_TRACE_SAMPLING_ENABLED", default=True)
TRACE_SAMPLING_BASE_RATE = _env_float("HIVE_TRACE_SAMPLING_BASE_RATE", 1.0)
TRACE_SAMPLING_DEGRADED_RATE = _env_float("HIVE_TRACE_SAMPLING_DEGRADED_RATE", 0.5)
TRACE_SAMPLING_SEVERE_RATE = _env_float("HIVE_TRACE_SAMPLING_SEVERE_RATE", 0.2)
TRACE_SAMPLING_DEGRADED_QUEUE_PCT = _env_int("HIVE_TRACE_SAMPLING_DEGRADED_QUEUE_PCT", 70)
TRACE_SAMPLING_SEVERE_QUEUE_PCT = _env_int("HIVE_TRACE_SAMPLING_SEVERE_QUEUE_PCT", 90)
TRACE_SAMPLING_ALWAYS_EVENT_TYPES = _env_csv(
    "HIVE_TRACE_SAMPLING_ALWAYS_EVENT_TYPES",
    default=[
        "proposal_created",
        "proposal_validated",
        "proposal_injected",
        "sandbox_run_started",
        "sandbox_run_completed",
        "sandbox_run_failed",
        "sandbox_run_timeout",
        "sandbox_run_rejected",
    ],
)
TRACE_SAMPLING_AUTOTUNE_ENABLED = _env_flag("HIVE_TRACE_SAMPLING_AUTOTUNE_ENABLED", default=True)
TRACE_SAMPLING_AUTOTUNE_INTERVAL_SEC = _env_int("HIVE_TRACE_SAMPLING_AUTOTUNE_INTERVAL_SEC", 5)
TRACE_SAMPLING_AUTOTUNE_STEP = _env_float("HIVE_TRACE_SAMPLING_AUTOTUNE_STEP", 0.05)
TRACE_SAMPLING_AUTOTUNE_MIN_RATE = _env_float("HIVE_TRACE_SAMPLING_AUTOTUNE_MIN_RATE", 0.05)
TRACE_SAMPLING_AUTOTUNE_TARGET_QUEUE_PCT = _env_int("HIVE_TRACE_SAMPLING_AUTOTUNE_TARGET_QUEUE_PCT", 60)
TRACE_SAMPLING_AUTOTUNE_HIGH_QUEUE_PCT = _env_int("HIVE_TRACE_SAMPLING_AUTOTUNE_HIGH_QUEUE_PCT", 85)
TRACE_SAMPLING_AUTOTUNE_DROP_RATIO_PCT = _env_float("HIVE_TRACE_SAMPLING_AUTOTUNE_DROP_RATIO_PCT", 1.0)
TRACE_EXPORT_MAX_LIMIT = _env_int("HIVE_TRACE_EXPORT_MAX_LIMIT", 10000)
TICK_BUDGET_MS = _env_int("HIVE_TICK_BUDGET_MS", 100)
TICK_METRICS_WINDOW = _env_int("HIVE_TICK_METRICS_WINDOW", 300)
AI_EXEC_MAX_RUNS = _env_int("HIVE_AI_EXEC_MAX_RUNS", 1000)
AI_EXEC_MAX_QUEUE = _env_int("HIVE_AI_EXEC_MAX_QUEUE", 300)
AI_EXEC_QUEUE_TTL_SEC = _env_int("HIVE_AI_EXEC_QUEUE_TTL_SEC", 30)
AI_EXEC_MAX_RUNTIME_SEC = _env_int("HIVE_AI_EXEC_MAX_RUNTIME_SEC", 20)
ZONE_STALL_WARN_TICKS = _env_int("HIVE_ZONE_STALL_WARN_TICKS", 200)
ZONE_STALL_FAIL_TICKS = _env_int("HIVE_ZONE_STALL_FAIL_TICKS", 0)
ENFORCE_USER_CAPABILITIES = _env_flag("HIVE_ENFORCE_USER_CAPABILITIES", default=False)
USER_CAPABILITIES_HEADER = _env_str("HIVE_USER_CAPABILITIES_HEADER", "X-User-Capabilities")


def get_ai_route_model_profile():
    return {
        "default_model": str(AI_ROUTE_MODEL_DEFAULT or "").strip() or str(AI_OLLAMA_MODEL or "phi3"),
        "routes": {
            "localize": str(AI_ROUTE_MODEL_LOCALIZE or "").strip(),
            "tutor": str(AI_ROUTE_MODEL_TUTOR or "").strip(),
            "hardware_explainer": str(AI_ROUTE_MODEL_HARDWARE_EXPLAINER or "").strip(),
            "intent_compile": str(AI_ROUTE_MODEL_INTENT_COMPILE or "").strip(),
        },
    }


def apply_ai_route_model_profile(default_model=None, route_models=None):
    global AI_ROUTE_MODEL_DEFAULT
    global AI_ROUTE_MODEL_LOCALIZE
    global AI_ROUTE_MODEL_TUTOR
    global AI_ROUTE_MODEL_HARDWARE_EXPLAINER
    global AI_ROUTE_MODEL_INTENT_COMPILE

    updated = get_ai_route_model_profile()
    if default_model is not None:
        AI_ROUTE_MODEL_DEFAULT = str(default_model or "").strip()
    route_models = dict(route_models or {})
    for route, model in route_models.items():
        route_name = str(route or "").strip().lower()
        model_name = str(model or "").strip()
        if route_name == "localize":
            AI_ROUTE_MODEL_LOCALIZE = model_name
        elif route_name == "tutor":
            AI_ROUTE_MODEL_TUTOR = model_name
        elif route_name == "hardware_explainer":
            AI_ROUTE_MODEL_HARDWARE_EXPLAINER = model_name
        elif route_name == "intent_compile":
            AI_ROUTE_MODEL_INTENT_COMPILE = model_name
    updated = get_ai_route_model_profile()
    return updated


def get_ai_route_model(route_class: str, fallback_model: str = "") -> str:
    route = str(route_class or "").strip().lower()
    if route == "localize" and AI_ROUTE_MODEL_LOCALIZE:
        return AI_ROUTE_MODEL_LOCALIZE
    if route == "tutor" and AI_ROUTE_MODEL_TUTOR:
        return AI_ROUTE_MODEL_TUTOR
    if route == "hardware_explainer" and AI_ROUTE_MODEL_HARDWARE_EXPLAINER:
        return AI_ROUTE_MODEL_HARDWARE_EXPLAINER
    if route == "intent_compile" and AI_ROUTE_MODEL_INTENT_COMPILE:
        return AI_ROUTE_MODEL_INTENT_COMPILE
    if AI_ROUTE_MODEL_DEFAULT:
        return AI_ROUTE_MODEL_DEFAULT
    configured = str(fallback_model or "").strip()
    if configured:
        return configured
    return str(AI_OLLAMA_MODEL or "phi3").strip() or "phi3"
