"""配置。

产品名只出现在这里和 apps/console/lib/brand.ts —— 改名成本 = 改两个常量。
商标检索未完成前，任何地方都不要再硬编码产品名。
"""
from __future__ import annotations

import os
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional

APP_NAME = "FlashOps"
APP_TAGLINE = "存储实验室无人值守执行层"

# 仓库根目录：.../flashops
REPO_ROOT = Path(__file__).resolve().parents[3]


def _env(key: str, default: str) -> str:
    return os.environ.get(f"FLASHOPS_{key}", default)


def _env_int(key: str, default: int) -> int:
    return int(os.environ.get(f"FLASHOPS_{key}", str(default)))


def _env_float(key: str, default: float) -> float:
    return float(os.environ.get(f"FLASHOPS_{key}", str(default)))


@dataclass(frozen=True)
class TimingPolicy:
    """时间策略。

    全部集中在这里，且引擎不直接读它 —— 引擎从 Snapshot 拿数值。
    这样"30 秒心跳超时"这类规则可以在测试里用 0.03 秒验证。
    """

    heartbeat_interval_s: float = 5.0
    heartbeat_degraded_after_s: float = 15.0
    heartbeat_lost_after_s: float = 30.0
    lease_ttl_s: float = 60.0
    lease_poll_timeout_s: float = 20.0
    step_default_timeout_s: float = 600.0
    recovery_settle_s: float = 20.0       # 恢复动作后等待主机回来的时间
    ac_cycle_off_s: float = 10.0          # AC 断电后的安全间隔（方案 §7.2）
    max_recovery_per_loop: int = 3
    max_recovery_total: int = 20


@dataclass(frozen=True)
class Settings:
    app_name: str = APP_NAME
    env: str = field(default_factory=lambda: _env("ENV", "development"))

    # 开发态：SQLite。生产：postgresql+asyncpg://...
    database_url: str = field(
        default_factory=lambda: _env(
            "DATABASE_URL", "sqlite+aiosqlite:///" + str(REPO_ROOT / "var" / "flashops.db")
        )
    )
    # 开发态：本地目录。生产：s3://minio:9000/flashops
    object_store_url: str = field(
        default_factory=lambda: _env("OBJECT_STORE_URL", str(REPO_ROOT / "var" / "objects"))
    )
    # 开发态：进程内 asyncio。生产：redis://... / nats://...
    bus_url: Optional[str] = field(default_factory=lambda: os.environ.get("FLASHOPS_BUS_URL"))
    # Agent 首次注册口令。开发态未配置时允许本机演示；生产态缺失时拒绝注册。
    agent_enrollment_token: Optional[str] = field(
        default_factory=lambda: os.environ.get("FLASHOPS_AGENT_ENROLLMENT_TOKEN")
    )

    api_host: str = field(default_factory=lambda: _env("API_HOST", "0.0.0.0"))
    api_port: int = field(default_factory=lambda: _env_int("API_PORT", 8000))
    cors_origins: str = field(default_factory=lambda: _env("CORS_ORIGINS", "http://localhost:3000"))

    # 引擎主循环的 tick 间隔。demo/测试里调小以加速。
    engine_tick_s: float = field(default_factory=lambda: _env_float("ENGINE_TICK_S", 0.5))
    # 演示/仿真加速倍率：1.0 = 真实速度
    time_scale: float = field(default_factory=lambda: _env_float("TIME_SCALE", 1.0))

    timing: TimingPolicy = field(default_factory=TimingPolicy)

    @property
    def is_sqlite(self) -> bool:
        return self.database_url.startswith("sqlite")

    @property
    def object_store_path(self) -> Path:
        return Path(self.object_store_url)


_settings: Optional[Settings] = None


def get_settings() -> Settings:
    global _settings
    if _settings is None:
        _settings = Settings()
    return _settings


def reset_settings() -> None:
    """测试用：让下一次 get_settings() 重新读环境变量。"""
    global _settings
    _settings = None
