"""Tests for complyform.core.profiles.cross_mappings — including error paths."""

from __future__ import annotations

from typing import TYPE_CHECKING
from unittest.mock import patch

if TYPE_CHECKING:
    from pathlib import Path

import pytest

from complyform.core.errors import ProfileBundleError
from complyform.core.profiles.cross_mappings import (
    _reset_cache,
    get_all,
    lookup,
    lookup_reverse,
)


@pytest.fixture(autouse=True)
def _clear_cache() -> None:
    _reset_cache()


# -------------------------------------------------------------------
# Happy paths
# -------------------------------------------------------------------


class TestLookup:
    def test_soc2_cc6_1(self) -> None:
        results = lookup("soc2", "CC6.1")
        assert len(results) >= 1
        assert all(r.source_framework == "soc2" for r in results)
        assert all(r.source_control == "CC6.1" for r in results)

    def test_no_match(self) -> None:
        results = lookup("nonexistent", "XX.1")
        assert results == []


class TestLookupReverse:
    def test_iso27001_a83(self) -> None:
        results = lookup_reverse("iso27001", "A.8.3")
        assert len(results) >= 1
        assert all(r.target_framework == "iso27001" for r in results)

    def test_no_match(self) -> None:
        results = lookup_reverse("nonexistent", "XX.1")
        assert results == []


class TestGetAll:
    def test_returns_list(self) -> None:
        all_entries = get_all()
        assert isinstance(all_entries, list)
        assert len(all_entries) >= 10


# -------------------------------------------------------------------
# Error / edge paths
# -------------------------------------------------------------------


class TestCrossMappingsMissing:
    def test_missing_file_returns_empty(self, tmp_path: Path) -> None:
        """When cross_mappings/index.yaml doesn't exist, returns empty index."""
        _reset_cache()
        with patch(
            "complyform.core.profiles.cross_mappings._PROFILES_DIR",
            tmp_path,
        ):
            results = get_all()
            assert results == []


class TestCrossMappingsMalformed:
    def test_invalid_yaml_schema(self, tmp_path: Path) -> None:
        _reset_cache()
        cm_dir = tmp_path / "cross_mappings"
        cm_dir.mkdir(exist_ok=True)
        bad_file = cm_dir / "index.yaml"
        bad_file.write_text("schema_version: 1\nmappings: not_a_list\n")
        with (
            patch(
                "complyform.core.profiles.cross_mappings._PROFILES_DIR",
                tmp_path,
            ),
            pytest.raises(ProfileBundleError),
        ):
            get_all()

    def test_missing_schema_version(self, tmp_path: Path) -> None:
        _reset_cache()
        cm_dir = tmp_path / "cross_mappings"
        cm_dir.mkdir(exist_ok=True)
        bad_file = cm_dir / "index.yaml"
        bad_file.write_text("mappings: []\n")
        with (
            patch(
                "complyform.core.profiles.cross_mappings._PROFILES_DIR",
                tmp_path,
            ),
            pytest.raises(ProfileBundleError),
        ):
            get_all()

    def test_bad_entry(self, tmp_path: Path) -> None:
        _reset_cache()
        cm_dir = tmp_path / "cross_mappings"
        cm_dir.mkdir(exist_ok=True)
        bad_file = cm_dir / "index.yaml"
        bad_file.write_text(
            "schema_version: 1\nmappings:\n  - source_framework: a\n"
            # missing required fields
        )
        with (
            patch(
                "complyform.core.profiles.cross_mappings._PROFILES_DIR",
                tmp_path,
            ),
            pytest.raises(ProfileBundleError),
        ):
            get_all()
