"""Global settings for MCP Bridge using Pydantic BaseSettings."""

from __future__ import annotations

import os
from pathlib import Path

from pydantic import Field
from pydantic_settings import BaseSettings


def _default_data_dir() -> Path:
    """Get or create the default data directory."""
    data_dir = Path(os.environ.get("MCP_BRIDGE_DATA_DIR", Path.home() / ".mcp-bridge"))
    data_dir.mkdir(parents=True, exist_ok=True)
    return data_dir


class InstanceLimits(BaseSettings):
    """Resource limits for server instances."""

    max_total_instances: int = Field(default=20, description="Maximum total concurrent instances across all servers")
    max_instances_per_server: int = Field(default=5, description="Maximum instances of a single server type")
    max_instances_per_agent: int = Field(default=10, description="Maximum instances per agent session")
    idle_timeout_seconds: int = Field(default=300, description="Seconds of idle before auto-shutdown")
    startup_timeout_seconds: int = Field(default=30, description="Max seconds to wait for server startup")
    health_check_interval_seconds: int = Field(default=60, description="Seconds between health checks")
    max_restart_attempts: int = Field(default=3, description="Max auto-restart attempts on crash")

    model_config = {"env_prefix": "MCP_BRIDGE_INSTANCE_"}


class SystemLimits(BaseSettings):
    """System resource thresholds."""

    max_memory_percent: float = Field(default=80.0, description="Max system memory % before refusing new instances")
    max_cpu_percent: float = Field(default=90.0, description="Max CPU % before refusing new instances")
    check_resources_before_start: bool = Field(
        default=True, description="Check system resources before starting instances"
    )

    model_config = {"env_prefix": "MCP_BRIDGE_SYSTEM_"}


class MetricsSettings(BaseSettings):
    """Metrics collection settings."""

    enabled: bool = Field(default=True, description="Enable metrics collection")
    retention_days: int = Field(default=30, description="Days to retain metric data")
    export_format: str = Field(default="json", description="Export format: json, csv, prometheus")

    model_config = {"env_prefix": "MCP_BRIDGE_METRICS_"}


class ManagementAPISettings(BaseSettings):
    """Management API settings for extension communication."""

    enabled: bool = Field(default=True, description="Enable the management REST API")
    host: str = Field(default="127.0.0.1", description="Management API host")
    port: int = Field(default=19420, description="Management API port")
    websocket_enabled: bool = Field(default=True, description="Enable WebSocket for real-time metrics")

    model_config = {"env_prefix": "MCP_BRIDGE_API_"}


class BridgeSettings(BaseSettings):
    """Main settings container for MCP Bridge."""

    # Directories
    data_dir: Path = Field(default_factory=_default_data_dir, description="Data directory for SQLite DBs and cache")
    catalog_dir: Path | None = Field(default=None, description="Custom catalog directory path")

    # Sub-settings
    instances: InstanceLimits = Field(default_factory=InstanceLimits)
    system: SystemLimits = Field(default_factory=SystemLimits)
    metrics: MetricsSettings = Field(default_factory=MetricsSettings)
    management_api: ManagementAPISettings = Field(default_factory=ManagementAPISettings)

    # Server
    server_name: str = Field(default="MCP Bridge", description="Name of the bridge server")
    server_transport: str = Field(default="stdio", description="Transport: stdio or http")
    server_port: int = Field(default=19421, description="Port for HTTP transport")

    # Logging
    log_level: str = Field(default="INFO", description="Log level: DEBUG, INFO, WARNING, ERROR")

    model_config = {"env_prefix": "MCP_BRIDGE_"}

    @property
    def db_path(self) -> Path:
        """Path to the main SQLite database."""
        return self.data_dir / "mcp_bridge.db"

    @property
    def metrics_db_path(self) -> Path:
        """Path to the metrics SQLite database."""
        return self.data_dir / "metrics.db"

    @property
    def resolved_catalog_dir(self) -> Path:
        """Resolved catalog directory - custom or default."""
        if self.catalog_dir:
            return self.catalog_dir
        # Default: look for catalog/ relative to the package
        pkg_catalog = Path(__file__).parent.parent.parent.parent / "catalog"
        if pkg_catalog.exists():
            return pkg_catalog
        # Fallback to data dir
        cat_dir = self.data_dir / "catalog"
        cat_dir.mkdir(parents=True, exist_ok=True)
        return cat_dir


# Singleton
_settings: BridgeSettings | None = None


def get_settings() -> BridgeSettings:
    """Get or create the global settings instance."""
    global _settings
    if _settings is None:
        _settings = BridgeSettings()
    return _settings


def reset_settings() -> None:
    """Reset settings (for testing)."""
    global _settings
    _settings = None
