import json
import shutil
import sys
import unittest
from datetime import UTC, datetime
from pathlib import Path

PROJECT_ROOT = Path(__file__).resolve().parent.parent
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

from core.io.umc_parser import parse_umc_file


class TestCSSModUMCParser(unittest.TestCase):
    """Sandbox unit testing system for validating the UMCParser."""

    def setUp(self):
        """Initializing the sandbox and an isolated test UMC file."""
        self.results_sandbox = Path(__file__).parent / "results_sandbox"
        self.results_dir = self.results_sandbox / "results"

        # Création des dossiers temporaires
        self.results_dir.mkdir(parents=True, exist_ok=True)

        self.timestamp = datetime.now(tz=UTC).strftime("%Y-%m-%d_%H-%M-%S")
        self.sandbox_input = self.results_sandbox / f"sandbox_umc_{self.timestamp}.txt"

        initial_content = (
            '"umc_mapcycle"\n'
            "{\n"
            '\t"Normal"\n'
            "\t{\n"
            '\t\t"maps_invote" "5"\n'
            '\t\t"de_dust2"\n'
            "\t\t{\n"
            '\t\t\t"weight" "1"\n'
            "\t\t}\n"
            '\t\t"de_inferno"\n'
            "\t\t{\n"
            '\t\t\t"tier" "2"\n'
            "\t\t}\n"
            "\t}\n"
            '\t"Aim"\n'
            "\t{\n"
            '\t\t"aim_map"\n'
            "\t\t{\n"
            "\t\t}\n"
            "\t}\n"
            "}\n"
        )
        self.sandbox_input.write_text(initial_content, encoding="utf-8")

    def tearDown(self):
        """Thorough cleaning of the sandbox after the test."""
        if self.results_sandbox.exists():
            shutil.rmtree(self.results_sandbox)

    def test_parser_integrity(self):
        """Verify that UMCParser reads, structures, and counts the data correctly."""
        data = parse_umc_file(self.sandbox_input)

        self.assertEqual(
            len(data), 2, f"Attendu : 2 catégories (Normal, Aim). Obtenu : {len(data)}"
        )
        self.assertIn("Normal", data)
        self.assertIn("Aim", data)

        self.assertEqual(data["Normal"]["options"].get("maps_invote"), "5")

        normal_maps = data["Normal"]["maps"]
        aim_maps = data["Aim"]["maps"]

        self.assertIn("de_dust2", normal_maps)
        self.assertIn("de_inferno", normal_maps)
        self.assertIn("aim_map", aim_maps)

        self.assertEqual(normal_maps["de_inferno"].get("tier"), "2")

        total_maps = sum(len(category.get("maps", {})) for category in data.values())
        self.assertEqual(total_maps, 3, f"Attendu : 3 maps au total. Obtenu : {total_maps}")

        output_json = self.results_dir / f"parse_result_{self.timestamp}.json"
        with output_json.open("w", encoding="utf-8") as f:
            json.dump(data, f, indent=4, ensure_ascii=False)

        self.assertTrue(output_json.exists())


if __name__ == "__main__":
    unittest.main()
