"""Tests for mcpaudit configuration file support."""

import tempfile
from pathlib import Path

import pytest

from mcpaudit.config import (
    AuditConfig,
    CONFIG_FILENAME,
    DEFAULT_CONFIG_CONTENT,
    _as_list,
    _parse_simple_yaml,
    create_default_config,
    load_config,
)


class TestAuditConfig:
    """Tests for the AuditConfig dataclass."""

    def test_defaults(self):
        config = AuditConfig()
        assert config.exclude_rules == []
        assert config.exclude_paths == []
        assert config.severity_threshold == "info"
        assert config.output_format == "text"
        assert config.custom_rules_dir == ""

    def test_from_dict_full(self):
        data = {
            "exclude_rules": ["AUTH-001", "RATE-001"],
            "exclude_paths": ["tests/*", "vendor/*"],
            "severity_threshold": "HIGH",
            "output_format": "JSON",
            "custom_rules_dir": "./custom/",
        }
        config = AuditConfig.from_dict(data)
        assert config.exclude_rules == ["AUTH-001", "RATE-001"]
        assert config.exclude_paths == ["tests/*", "vendor/*"]
        assert config.severity_threshold == "high"
        assert config.output_format == "json"
        assert config.custom_rules_dir == "./custom/"

    def test_from_dict_empty(self):
        config = AuditConfig.from_dict({})
        assert config.exclude_rules == []
        assert config.severity_threshold == "info"

    def test_from_dict_single_string_rule(self):
        config = AuditConfig.from_dict({"exclude_rules": "AUTH-001"})
        assert config.exclude_rules == ["AUTH-001"]


class TestAsList:
    """Tests for the _as_list helper."""

    def test_list_input(self):
        assert _as_list(["a", "b"]) == ["a", "b"]

    def test_string_input(self):
        assert _as_list("single") == ["single"]

    def test_empty_string(self):
        assert _as_list("") == []

    def test_none_input(self):
        assert _as_list(None) == []

    def test_int_list(self):
        assert _as_list([1, 2, 3]) == ["1", "2", "3"]


class TestParseSimpleYaml:
    """Tests for the simple YAML parser."""

    def test_key_value(self):
        result = _parse_simple_yaml("severity_threshold: high")
        assert result == {"severity_threshold": "high"}

    def test_quoted_value(self):
        result = _parse_simple_yaml('output_format: "json"')
        assert result == {"output_format": "json"}

    def test_single_quoted_value(self):
        result = _parse_simple_yaml("output_format: 'html'")
        assert result == {"output_format": "html"}

    def test_list_block(self):
        yaml_content = "exclude_rules:\n  - AUTH-001\n  - RATE-001"
        result = _parse_simple_yaml(yaml_content)
        assert result == {"exclude_rules": ["AUTH-001", "RATE-001"]}

    def test_comments_skipped(self):
        yaml_content = "# This is a comment\nseverity_threshold: high\n# Another comment"
        result = _parse_simple_yaml(yaml_content)
        assert result == {"severity_threshold": "high"}

    def test_empty_lines_skipped(self):
        yaml_content = "\n\nseverity_threshold: high\n\n"
        result = _parse_simple_yaml(yaml_content)
        assert result == {"severity_threshold": "high"}

    def test_empty_content(self):
        assert _parse_simple_yaml("") == {}

    def test_only_comments(self):
        assert _parse_simple_yaml("# comment\n# another") == {}

    def test_mixed_keys_and_lists(self):
        yaml_content = (
            "severity_threshold: medium\n"
            "exclude_rules:\n"
            "  - SQL-001\n"
            "  - CMD-001\n"
            "output_format: json"
        )
        result = _parse_simple_yaml(yaml_content)
        assert result["severity_threshold"] == "medium"
        assert result["exclude_rules"] == ["SQL-001", "CMD-001"]
        assert result["output_format"] == "json"

    def test_quoted_list_items(self):
        yaml_content = 'exclude_paths:\n  - "tests/*"\n  - "vendor/*"'
        result = _parse_simple_yaml(yaml_content)
        assert result["exclude_paths"] == ["tests/*", "vendor/*"]

    def test_list_at_end_of_file(self):
        yaml_content = "exclude_rules:\n  - AUTH-001"
        result = _parse_simple_yaml(yaml_content)
        assert result == {"exclude_rules": ["AUTH-001"]}


class TestLoadConfig:
    """Tests for loading config from files."""

    def test_load_nonexistent_returns_defaults(self):
        config = load_config(Path("/nonexistent/.mcpaudit.yml"))
        assert config == AuditConfig()

    def test_load_valid_config(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            config_path = Path(tmpdir) / CONFIG_FILENAME
            config_path.write_text(
                "severity_threshold: high\n"
                "exclude_rules:\n"
                "  - AUTH-001\n",
                encoding="utf-8",
            )
            config = load_config(config_path)
            assert config.severity_threshold == "high"
            assert config.exclude_rules == ["AUTH-001"]

    def test_load_empty_config(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            config_path = Path(tmpdir) / CONFIG_FILENAME
            config_path.write_text("", encoding="utf-8")
            config = load_config(config_path)
            assert config == AuditConfig()


class TestCreateDefaultConfig:
    """Tests for creating default config file."""

    def test_creates_file(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            path = create_default_config(Path(tmpdir))
            assert path.exists()
            assert path.name == CONFIG_FILENAME

    def test_content_matches_default(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            path = create_default_config(Path(tmpdir))
            content = path.read_text(encoding="utf-8")
            assert content == DEFAULT_CONFIG_CONTENT

    def test_default_config_parseable(self):
        """The default config content should parse without errors."""
        result = _parse_simple_yaml(DEFAULT_CONFIG_CONTENT)
        assert isinstance(result, dict)
