from __future__ import annotations

import unittest

from mais_humana.repository_mesh import MeshEnvironment, MeshEnvironmentKind, RepositoryTarget, build_mesh_report
from mais_humana.repository_mesh_naming import (
    NamingStatus,
    candidate_names,
    central_folder_for_name,
    decide_naming,
    naming_rows,
    plataform_to_platform,
    platform_to_plataform,
)
from mais_humana.repository_mesh_reconciliation import ReconciliationStatus, build_reconciliation_plan
from tests.helpers import make_tmp
from tests.test_repository_mesh import FakeGit, make_repo


class RepositoryMeshNamingTests(unittest.TestCase):
    def test_platform_and_plataform_helpers_are_reversible_for_suffixes(self) -> None:
        self.assertEqual(platform_to_plataform("tudo-para-ia-ui-platform"), "tudo-para-ia-ui-plataform")
        self.assertEqual(plataform_to_platform("tudo-para-ia-docs-plataform"), "tudo-para-ia-docs-platform")
        self.assertEqual(platform_to_plataform("sem-sufixo"), "sem-sufixo")
        self.assertEqual(central_folder_for_name("Tudo Para IA UI Platform", index=14), "14_repo_tudo-para-ia-ui-platform")

    def test_candidate_names_include_expected_alias_canonical_and_suffix_variant(self) -> None:
        target = RepositoryTarget(
            "alpha-platform",
            "admin/alpha-platform",
            "alpha-platform",
            "01_alpha",
            aliases=("alpha",),
            canonical_name="alpha-plataform",
            requires_nominal_reconciliation=True,
        )
        self.assertEqual(
            candidate_names(target),
            ("alpha-platform", "alpha-plataform", "alpha",),
        )

    def test_decide_naming_marks_exact_alias_missing_and_conflict(self) -> None:
        root = make_tmp()
        target = RepositoryTarget("alpha-new", "admin/alpha", "alpha-new", "01_alpha", aliases=("alpha-old",))

        self.assertEqual(decide_naming(root, target).status, NamingStatus.MISSING)

        (root / "alpha-old").mkdir()
        alias = decide_naming(root, target)
        self.assertEqual(alias.status, NamingStatus.ALIAS)
        self.assertEqual(alias.selected_name, "alpha-old")

        (root / "alpha-new").mkdir()
        conflict = decide_naming(root, target)
        self.assertEqual(conflict.status, NamingStatus.CONFLICT)

        target = RepositoryTarget(
            "beta-new",
            "admin/beta",
            "beta-new",
            "01_beta",
            aliases=("beta-old",),
            canonical_name="beta-canonical",
        )
        (root / "beta-old").mkdir()
        (root / "beta-canonical").mkdir()
        conflict = decide_naming(root, target)
        self.assertEqual(conflict.status, NamingStatus.CONFLICT)
        self.assertIn("CONFLICT", "\n".join(",".join(row) for row in naming_rows((conflict,))).upper())

    def test_reconciliation_blocks_when_two_alias_variants_exist(self) -> None:
        root = make_tmp()
        repo_a = make_repo(root, "alpha-old")
        repo_b = make_repo(root, "alpha-canonical")
        fake = FakeGit()
        fake.set_repo(repo_a, remote="https://git.ami.app.br/admin/alpha.git")
        fake.set_repo(repo_b, remote="https://git.ami.app.br/admin/alpha.git")
        target = RepositoryTarget(
            "alpha-new",
            "admin/alpha",
            "alpha-new",
            "01_alpha",
            aliases=("alpha-old",),
            canonical_name="alpha-canonical",
            requires_nominal_reconciliation=True,
        )
        env = MeshEnvironment("primary", MeshEnvironmentKind.WINDOWS_PRIMARY, str(root), "test")
        report = build_mesh_report(root, targets=(target,), environments=(env,), runner=fake)
        plan = build_reconciliation_plan(report)
        receipt = plan.receipts[0]
        self.assertEqual(receipt.status, ReconciliationStatus.MANUAL_DECISION_REQUIRED)
        self.assertEqual(receipt.naming_decisions[0].status, NamingStatus.CONFLICT)
        self.assertTrue(any("conflito nominal" in operation.title.lower() for operation in receipt.operations))


if __name__ == "__main__":
    unittest.main()
