"""Configuration management for MCGhidra.

Handles environment variables, default settings, and runtime configuration.
"""

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


@dataclass
class DockerConfig:
    """Docker-specific configuration."""

    # Docker image settings
    image_name: str = "mcghidra"
    image_tag: str = field(default_factory=lambda: os.environ.get("MCGHIDRAMCP_VERSION", "latest"))

    # Default container settings
    default_port: int = field(default_factory=lambda: int(os.environ.get("MCGHIDRA_PORT", "8192")))
    default_memory: str = field(default_factory=lambda: os.environ.get("MCGHIDRA_MAXMEM", "2G"))

    # Project directory (for building)
    project_dir: Optional[Path] = None

    # Auto-start settings
    auto_start_enabled: bool = field(default_factory=lambda: os.environ.get("MCGHIDRA_DOCKER_AUTO", "false").lower() == "true")
    auto_start_wait: bool = True
    auto_start_timeout: float = 300.0


# Docker configuration instance
_docker_config: Optional[DockerConfig] = None


def get_docker_config() -> DockerConfig:
    """Get the Docker configuration instance."""
    global _docker_config
    if _docker_config is None:
        _docker_config = DockerConfig()
    return _docker_config


def set_docker_config(config: DockerConfig) -> None:
    """Set the Docker configuration instance."""
    global _docker_config
    _docker_config = config


@dataclass
class MCGhidraConfig:
    """Configuration for MCGhidra server."""

    # Ghidra connection settings
    ghidra_host: str = field(default_factory=lambda: os.environ.get("GHIDRA_HOST", "localhost"))
    default_port: Optional[int] = None

    # Port scanning ranges for instance discovery
    quick_discovery_range: range = field(default_factory=lambda: range(18489, 18499))
    full_discovery_range: range = field(default_factory=lambda: range(18400, 18600))

    # HTTP client settings
    request_timeout: float = 30.0
    discovery_timeout: float = 0.5

    # Pagination defaults
    default_page_size: int = 50
    max_page_size: int = 500

    # Cursor management
    cursor_ttl_seconds: int = 300  # 5 minutes
    max_cursors_per_session: int = 100

    # Response size limits (for return_all guard)
    max_response_tokens: int = 8000       # Hard budget — guard triggers above this
    large_response_threshold: int = 4000  # Warn above this in normal pagination

    # Expected API version
    expected_api_version: int = 2

    # Feedback collection
    feedback_enabled: bool = field(
        default_factory=lambda: os.environ.get("MCGHIDRA_FEEDBACK", "true").lower() == "true"
    )
    feedback_db_path: str = field(
        default_factory=lambda: os.environ.get(
            "MCGHIDRA_FEEDBACK_DB",
            str(Path.home() / ".mcghidra" / "feedback.db"),
        )
    )

    # Resource caps for enumeration endpoints
    resource_caps: dict = field(default_factory=lambda: {
        "functions": 1000,
        "strings": 500,
        "data": 1000,
        "structs": 500,
        "xrefs": 500,
        "symbols": 1000,
        "segments": 500,
        "variables": 1000,
        "namespaces": 500,
        "classes": 500,
        "bookmarks": 1000,
        "enums": 500,
        "typedefs": 500,
    })

    def __post_init__(self):
        """Validate configuration after initialization."""
        if self.default_page_size > self.max_page_size:
            self.default_page_size = self.max_page_size


# Global configuration instance (can be replaced for testing)
_config: Optional[MCGhidraConfig] = None


def get_config() -> MCGhidraConfig:
    """Get the global configuration instance."""
    global _config
    if _config is None:
        _config = MCGhidraConfig()
    return _config


def set_config(config: MCGhidraConfig) -> None:
    """Set the global configuration instance."""
    global _config
    _config = config


def reset_config() -> None:
    """Reset to default configuration."""
    global _config
    _config = None
