from __future__ import annotations

import json
import unittest

from mais_humana.canonical_migration import (
    AcceptanceStatus,
    CANONICAL_PROJECT_ID,
    CURRENT_PROJECT_ID,
    build_canonical_migration_plan,
    build_migration_acceptance_cases,
    migration_plan_markdown,
    migration_plan_payload,
)
from mais_humana.cli import main
from mais_humana.storage import table_counts
from tests.helpers import make_tmp


class CanonicalMigrationTests(unittest.TestCase):
    def test_runtime_plan_models_canonical_aliases_and_controls(self) -> None:
        plan = build_canonical_migration_plan(use_generated=False)

        self.assertEqual(plan.canonical_project_id, CANONICAL_PROJECT_ID)
        self.assertEqual(plan.current_project_id, CURRENT_PROJECT_ID)
        self.assertGreaterEqual(plan.controls_count, 8)
        self.assertGreaterEqual(len(plan.acceptance_cases), 2000)
        self.assertIn("SEC_E_NO_CREDENTIALS", plan.blockers)
        self.assertIn("Plano de migracao canonica", migration_plan_markdown(plan, limit_cases=3))

    def test_owner_platform_alias_requires_canonical_rewrite(self) -> None:
        cases = build_migration_acceptance_cases()
        matching = [
            case
            for case in cases
            if case.target_name == CANONICAL_PROJECT_ID
            and case.field_name == "ownerPlatformId"
            and case.candidate_value == CURRENT_PROJECT_ID
        ]

        self.assertTrue(matching)
        self.assertTrue(all(case.accepted for case in matching))
        self.assertTrue(any(case.status == AcceptanceStatus.CANONICAL_FIELD_REWRITE_REQUIRED for case in matching))

    def test_payload_is_compact_but_preserves_totals(self) -> None:
        plan = build_canonical_migration_plan(use_generated=False)
        payload = migration_plan_payload(plan, limit_cases=5)

        self.assertEqual(payload["canonical_project_id"], CANONICAL_PROJECT_ID)
        self.assertEqual(len(payload["acceptance_cases"]), 5)
        self.assertEqual(payload["acceptance_cases_total"], len(plan.acceptance_cases))
        self.assertIn(CURRENT_PROJECT_ID, payload["accepted_project_ids"])

    def test_cli_writes_project_central_and_sql_artifacts(self) -> None:
        root = make_tmp()
        project = root / "tudo-para-ia-mais-humana"
        central = root / "central" / "15_repo_tudo-para-ia-mais-humana-platform"

        code = main(
            [
                "canonical-migration-plan",
                "--project-root",
                str(project),
                "--central-platform-folder",
                str(central),
                "--no-generated",
                "--limit",
                "3",
            ]
        )

        self.assertEqual(code, 0)
        self.assertTrue((project / "dados" / "canonical-migration-plan.json").exists())
        self.assertTrue((project / "matrizes" / "canonical-migration-acceptance-cases.csv").exists())
        self.assertTrue((project / "matrizes" / "canonical-migration-controls.csv").exists())
        self.assertTrue((project / "ecossistema" / "CANONICAL-MIGRATION-PLAN.md").exists())
        self.assertTrue((central / "reports" / "EXECUTADO__canonical-migration-plan.md").exists())
        payload = json.loads((project / "dados" / "canonical-migration-plan.json").read_text(encoding="utf-8"))
        self.assertEqual(payload["canonical_project_id"], CANONICAL_PROJECT_ID)
        self.assertGreaterEqual(payload["acceptance_cases_total"], 2000)
        self.assertGreaterEqual(table_counts(project / "controle-semantico.sqlite").get("files", 0), 4)
        self.assertGreaterEqual(table_counts(central / "controle-semantico.sqlite").get("files", 0), 1)


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

