"""Configuration schema for .autodebug.yml files."""

from __future__ import annotations

from pathlib import Path
from typing import Any, Dict, List, Optional

import yaml

# Default configuration values
DEFAULT_CONFIG = {
    "version": 1,
    "environment": {
        "tier": "A",  # A (pip freeze) or B (lockfile)
        "lockfile": None,  # poetry.lock, Pipfile.lock
        "base_image": None,  # Custom Docker base image
        "python_version": None,  # Auto-detect or override
    },
    "capture": {
        "files": {
            "include": [
                "config/**/*.yaml",
                "config/**/*.yml",
                "config/**/*.json",
                "*.yaml",
                "*.yml",
                "*.json",
                "*.toml",
                "*.ini",
            ],
            "exclude": [
                "**/*.pem",
                "**/*.key",
                "**/secrets/**",
                "**/.env",
                "**/.env.*",
            ],
            "max_size_kb": 100,
        },
    },
    "redaction": {
        "env_vars": [
            "DATABASE_URL",
            "API_KEY",
            "SECRET_KEY",
            "AWS_ACCESS_KEY_ID",
            "AWS_SECRET_ACCESS_KEY",
        ],
        "patterns": [
            "password",
            "secret",
            "token",
            "credential",
        ],
    },
}


class Config:
    """AutoDebug configuration."""

    def __init__(self, data: Dict[str, Any]):
        self._data = data

    @classmethod
    def load(cls, path: Optional[Path] = None) -> Config:
        """Load configuration from .autodebug.yml file.

        Args:
            path: Path to config file. If None, searches current directory.

        Returns:
            Config instance with merged defaults.
        """
        if path is None:
            # Search for config file
            for name in [".autodebug.yml", ".autodebug.yaml", "autodebug.yml"]:
                candidate = Path.cwd() / name
                if candidate.exists():
                    path = candidate
                    break

        if path is None or not path.exists():
            # Return defaults
            return cls(DEFAULT_CONFIG.copy())

        with open(path, encoding="utf-8") as f:
            user_config = yaml.safe_load(f) or {}

        # Merge with defaults
        merged = _deep_merge(DEFAULT_CONFIG.copy(), user_config)
        return cls(merged)

    @property
    def version(self) -> int:
        return self._data.get("version", 1)

    @property
    def environment_tier(self) -> str:
        return self._data.get("environment", {}).get("tier", "A")

    @property
    def lockfile(self) -> Optional[str]:
        return self._data.get("environment", {}).get("lockfile")

    @property
    def base_image(self) -> Optional[str]:
        return self._data.get("environment", {}).get("base_image")

    @property
    def python_version(self) -> Optional[str]:
        return self._data.get("environment", {}).get("python_version")

    @property
    def file_include_patterns(self) -> List[str]:
        return self._data.get("capture", {}).get("files", {}).get("include", [])

    @property
    def file_exclude_patterns(self) -> List[str]:
        return self._data.get("capture", {}).get("files", {}).get("exclude", [])

    @property
    def file_max_size_kb(self) -> int:
        return self._data.get("capture", {}).get("files", {}).get("max_size_kb", 100)

    @property
    def redact_env_vars(self) -> List[str]:
        return self._data.get("redaction", {}).get("env_vars", [])

    @property
    def redact_patterns(self) -> List[str]:
        return self._data.get("redaction", {}).get("patterns", [])

    def to_dict(self) -> Dict[str, Any]:
        """Return configuration as dictionary."""
        return self._data.copy()


def _deep_merge(base: Dict, override: Dict) -> Dict:
    """Deep merge two dictionaries."""
    result = base.copy()
    for key, value in override.items():
        if key in result and isinstance(result[key], dict) and isinstance(value, dict):
            result[key] = _deep_merge(result[key], value)
        else:
            result[key] = value
    return result


def generate_example_config() -> str:
    """Generate example .autodebug.yml content."""
    return """# AutoDebug Configuration
# See: https://docs.autodebug.dev/configuration

version: 1

environment:
  # Environment replay tier:
  # - A: pip freeze (default, most compatible)
  # - B: Use lockfile (poetry.lock or Pipfile.lock)
  tier: A

  # Lockfile path (for tier B)
  # lockfile: poetry.lock

  # Custom Docker base image (for system dependencies)
  # base_image: myorg/python-with-deps:3.11

  # Python version override (default: auto-detect)
  # python_version: "3.11"

capture:
  files:
    # Patterns for files to include in capture
    include:
      - "config/**/*.yaml"
      - "config/**/*.yml"
      - "config/**/*.json"
      - "*.yaml"
      - "*.yml"
      - "*.json"
      - "*.toml"
      - "*.ini"

    # Patterns for files to exclude
    exclude:
      - "**/*.pem"
      - "**/*.key"
      - "**/secrets/**"
      - "**/.env"
      - "**/.env.*"

    # Maximum file size to capture (KB)
    max_size_kb: 100

redaction:
  # Environment variables to always redact
  env_vars:
    - DATABASE_URL
    - API_KEY
    - SECRET_KEY
    - AWS_ACCESS_KEY_ID
    - AWS_SECRET_ACCESS_KEY

  # Patterns to redact in values
  patterns:
    - password
    - secret
    - token
    - credential
"""
