"""Tests for complyform.core.greenfield.dependency_resolver — DAG resolution."""

from __future__ import annotations

import pytest

from complyform.core.errors import DependencyCycleError
from complyform.core.greenfield.dependency_resolver import resolve_dependencies


class TestSimpleDag:
    def test_topological_order(self) -> None:
        entries = [
            {
                "template": "kms_key_ring",
                "resource_type": "google_kms_key_ring",
                "required_by": "google_storage_bucket",
            },
            {
                "template": "kms_crypto_key",
                "resource_type": "google_kms_crypto_key",
                "required_by": "google_storage_bucket",
                "depends_on": ["kms_key_ring"],
            },
        ]
        result = resolve_dependencies(entries)
        names = [d.template_name for d in result]
        assert names.index("kms_key_ring") < names.index("kms_crypto_key")


class TestDeduplication:
    def test_two_frameworks_same_dep(self) -> None:
        entries = [
            {
                "template": "kms_key_ring",
                "resource_type": "google_kms_key_ring",
                "required_by": "google_storage_bucket",
            },
            {
                "template": "kms_key_ring",
                "resource_type": "google_kms_key_ring",
                "required_by": "google_sql_database_instance",
            },
        ]
        result = resolve_dependencies(entries)
        assert len(result) == 1
        assert "google_storage_bucket" in result[0].required_by
        assert "google_sql_database_instance" in result[0].required_by


class TestCycleDetection:
    def test_raises_cycle_error(self) -> None:
        entries = [
            {
                "template": "a",
                "resource_type": "type_a",
                "required_by": "",
                "depends_on": ["b"],
            },
            {
                "template": "b",
                "resource_type": "type_b",
                "required_by": "",
                "depends_on": ["a"],
            },
        ]
        with pytest.raises(DependencyCycleError):
            resolve_dependencies(entries)


class TestEmptyDependencies:
    def test_empty_list(self) -> None:
        assert resolve_dependencies([]) == []


class TestIndependentDeps:
    def test_multiple_unrelated(self) -> None:
        entries = [
            {
                "template": "dep_a",
                "resource_type": "type_a",
                "required_by": "x",
            },
            {
                "template": "dep_b",
                "resource_type": "type_b",
                "required_by": "y",
            },
        ]
        result = resolve_dependencies(entries)
        assert len(result) == 2
        names = {d.template_name for d in result}
        assert names == {"dep_a", "dep_b"}
