# #region TestArchiveParser [C:2] [TYPE Module]
#
# @PURPOSE: Unit tests for MigrationArchiveParser ZIP extraction contract.
# @LAYER Domain
# @RELATION  DEPENDS_ON -> [MigrationArchiveParserModule]
#
import os
from pathlib import Path
import sys
import tempfile
import zipfile

import yaml

backend_dir = str(Path(__file__).parent.parent.parent.parent.resolve())
if backend_dir not in sys.path:
    sys.path.insert(0, backend_dir)

from src.core.migration.archive_parser import MigrationArchiveParser


# #region test_extract_objects_from_zip_collects_all_types [C:2] [TYPE Function]
# @RELATION  BINDS_TO -> TestArchiveParser
# @PURPOSE: Verify archive parser collects dashboard/chart/dataset YAML objects into typed buckets.
# @TEST_CONTRACT: zip_archive_fixture -> typed dashboard/chart/dataset extraction buckets
# @TEST_SCENARIO: archive_with_supported_objects_extracts_all_types -> One YAML file per supported type lands in matching bucket.
# @TEST_EDGE: missing_field -> Missing typed folder prevents that object class from being extracted.
# @TEST_EDGE: invalid_type -> Unsupported file layout is ignored by typed extraction buckets.
# @TEST_EDGE: external_fail -> Corrupt archive would fail extraction before typed buckets are returned.
def test_extract_objects_from_zip_collects_all_types():
    parser = MigrationArchiveParser()
    with tempfile.TemporaryDirectory() as td:
        td_path = Path(td)
        zip_path = td_path / "objects.zip"
        src_dir = td_path / "src"
        (src_dir / "dashboards").mkdir(parents=True)
        (src_dir / "charts").mkdir(parents=True)
        (src_dir / "datasets").mkdir(parents=True)

        with open(src_dir / "dashboards" / "dash.yaml", "w") as file_obj:
            yaml.dump(
                {"uuid": "dash-u1", "dashboard_title": "D1", "json_metadata": "{}"},
                file_obj,
            )
        with open(src_dir / "charts" / "chart.yaml", "w") as file_obj:
            yaml.dump(
                {"uuid": "chart-u1", "slice_name": "C1", "viz_type": "bar"}, file_obj
            )
        with open(src_dir / "datasets" / "dataset.yaml", "w") as file_obj:
            yaml.dump(
                {"uuid": "ds-u1", "table_name": "orders", "database_uuid": "db-u1"},
                file_obj,
            )

        with zipfile.ZipFile(zip_path, "w") as zip_obj:
            for root, _, files in os.walk(src_dir):
                for file_name in files:
                    file_path = Path(root) / file_name
                    zip_obj.write(file_path, file_path.relative_to(src_dir))

        extracted = parser.extract_objects_from_zip(str(zip_path))

    if len(extracted["dashboards"]) != 1:
        raise AssertionError("dashboards extraction size mismatch")
    if extracted["dashboards"][0]["uuid"] != "dash-u1":
        raise AssertionError("dashboard uuid mismatch")
    if len(extracted["charts"]) != 1:
        raise AssertionError("charts extraction size mismatch")
    if extracted["charts"][0]["uuid"] != "chart-u1":
        raise AssertionError("chart uuid mismatch")
    if len(extracted["datasets"]) != 1:
        raise AssertionError("datasets extraction size mismatch")
    if extracted["datasets"][0]["uuid"] != "ds-u1":
        raise AssertionError("dataset uuid mismatch")


# #endregion test_extract_objects_from_zip_collects_all_types
# #endregion TestArchiveParser
