"""
OmniSec Core Configuration
Centralised config management with env-var override support.
"""

import os
import json
from dataclasses import dataclass, field, asdict
from typing import Optional


@dataclass
class OmniConfig:
    """
    Centralised configuration for all OmniSec modules.
    Every field can be overridden by a corresponding environment variable.

    Example:
        >>> cfg = OmniConfig(gcs_bucket="my-bucket", ai_model="gpt-4")
        >>> cfg.save("omnisec.json")
        >>> cfg2 = OmniConfig.load("omnisec.json")
    """

    # ── AI ──────────────────────────────────────────────────────────
    ai_model: str = field(default_factory=lambda: os.getenv("OMNISEC_AI_MODEL", "claude-sonnet-4-6"))
    ai_api_key: Optional[str] = field(default_factory=lambda: os.getenv("ANTHROPIC_API_KEY"))
    ai_max_tokens: int = field(default_factory=lambda: int(os.getenv("OMNISEC_AI_MAX_TOKENS", "1024")))

    # ── MFT ─────────────────────────────────────────────────────────
    mft_host: str = field(default_factory=lambda: os.getenv("OMNISEC_MFT_HOST", "localhost"))
    mft_port: int = field(default_factory=lambda: int(os.getenv("OMNISEC_MFT_PORT", "22")))
    mft_username: Optional[str] = field(default_factory=lambda: os.getenv("OMNISEC_MFT_USER"))
    mft_password: Optional[str] = field(default_factory=lambda: os.getenv("OMNISEC_MFT_PASS"))
    mft_key_path: Optional[str] = field(default_factory=lambda: os.getenv("OMNISEC_MFT_KEY"))
    mft_encrypt: bool = field(default_factory=lambda: os.getenv("OMNISEC_MFT_ENCRYPT", "true").lower() == "true")

    # ── GCS ─────────────────────────────────────────────────────────
    gcs_project: Optional[str] = field(default_factory=lambda: os.getenv("GOOGLE_CLOUD_PROJECT"))
    gcs_bucket: Optional[str] = field(default_factory=lambda: os.getenv("OMNISEC_GCS_BUCKET"))
    gcs_credentials: Optional[str] = field(default_factory=lambda: os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
    gcs_region: str = field(default_factory=lambda: os.getenv("OMNISEC_GCS_REGION", "us-central1"))

    # ── Security ────────────────────────────────────────────────────
    sec_default_hash: str = field(default_factory=lambda: os.getenv("OMNISEC_HASH_ALG", "sha256"))
    sec_aes_key_size: int = field(default_factory=lambda: int(os.getenv("OMNISEC_AES_BITS", "256")))
    sec_pbkdf2_iterations: int = field(default_factory=lambda: int(os.getenv("OMNISEC_PBKDF2_ITER", "390000")))

    # ── Internet ────────────────────────────────────────────────────
    net_timeout: int = field(default_factory=lambda: int(os.getenv("OMNISEC_NET_TIMEOUT", "10")))
    net_retries: int = field(default_factory=lambda: int(os.getenv("OMNISEC_NET_RETRIES", "3")))
    net_user_agent: str = field(
        default_factory=lambda: os.getenv(
            "OMNISEC_USER_AGENT",
            "OmniSec/1.0 (+https://github.com/omnisec/omnisec)"
        )
    )

    def save(self, path: str) -> None:
        """Persist config to a JSON file."""
        with open(path, "w") as f:
            json.dump(asdict(self), f, indent=2)

    @classmethod
    def load(cls, path: str) -> "OmniConfig":
        """Load config from a JSON file."""
        with open(path) as f:
            data = json.load(f)
        return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__})

    def to_dict(self) -> dict:
        return asdict(self)

    def __repr__(self) -> str:
        safe = asdict(self)
        for secret in ("ai_api_key", "mft_password"):
            if safe.get(secret):
                safe[secret] = "****"
        return f"OmniConfig({safe})"
