#!/usr/bin/env python3

import hashlib
import importlib.machinery
import importlib.util
import json
import os
import subprocess
import tarfile
import tempfile
import unittest
from pathlib import Path


SCRIPT_DIR = Path(__file__).resolve().parent
PLATFORM_ROOT = SCRIPT_DIR.parent.parent
BUILDER = SCRIPT_DIR / "build-module-foundry-filter-toggle-artifact.mjs"
RUNNER_PATH = SCRIPT_DIR / "nodedc-deploy"
PATCH_ID = "module-foundry-filter-toggle-unit-001"
EXPECTED_FILES = (
    "apps/catalog/src/MapFixturePreview.tsx",
    "apps/catalog/src/mapPresentationProfile.ts",
    "scripts/map-presentation-filters.test.mjs",
)


def load_runner():
    loader = importlib.machinery.SourceFileLoader(
        "nodedc_module_foundry_filter_toggle_artifact",
        str(RUNNER_PATH),
    )
    spec = importlib.util.spec_from_loader(loader.name, loader)
    module = importlib.util.module_from_spec(spec)
    loader.exec_module(module)
    return module


RUNNER = load_runner()


class ModuleFoundryFilterToggleArtifactTest(unittest.TestCase):
    def build(self, artifact_dir):
        environment = os.environ.copy()
        environment["NODEDC_DEPLOY_ARTIFACT_DIR"] = str(artifact_dir)
        completed = subprocess.run(
            ["node", str(BUILDER), PATCH_ID],
            cwd=PLATFORM_ROOT,
            env=environment,
            check=True,
            capture_output=True,
            text=True,
        )
        return json.loads(completed.stdout)

    def test_builder_is_deterministic_exact_scope_and_runner_compatible(self):
        with tempfile.TemporaryDirectory(prefix="nodedc-foundry-filter-toggle-") as directory:
            root = Path(directory)
            first = self.build(root / "first")
            second = self.build(root / "second")
            first_artifact = Path(first["artifact"])
            second_artifact = Path(second["artifact"])

            self.assertEqual(first_artifact.read_bytes(), second_artifact.read_bytes())
            self.assertEqual(first["sha256"], hashlib.sha256(first_artifact.read_bytes()).hexdigest())
            self.assertEqual(tuple(first["files"]), EXPECTED_FILES)

            extracted = root / "loaded"
            extracted.mkdir()
            manifest, entries, payload = RUNNER.load_artifact(first_artifact, extracted)
            self.assertEqual(manifest["component"], "module-foundry")
            self.assertEqual(tuple(entries), EXPECTED_FILES)
            self.assertEqual(RUNNER.component_services("module-foundry", entries), ("nodedc-module-foundry",))

            helper = (payload / EXPECTED_FILES[1]).read_text(encoding="utf-8")
            preview = (payload / EXPECTED_FILES[0]).read_text(encoding="utf-8")
            regression = (payload / EXPECTED_FILES[2]).read_text(encoding="utf-8")
            self.assertIn("toggleMapPresentationFacetSelection", helper)
            self.assertIn("return unconstrained", helper)
            self.assertIn("filters: toggleMapPresentationFacetSelection(filters, field, value)", preview)
            self.assertIn("interactive deselect of the last chip removes the facet constraint", regression)

            with tarfile.open(first_artifact, "r:gz") as archive:
                members = archive.getmembers()
                names = [member.name for member in members]
                regular_payloads = [
                    archive.extractfile(member).read()
                    for member in members
                    if member.isfile()
                ]
            self.assertFalse(any(Path(name).name.startswith("._") for name in names))
            self.assertFalse(any("/.git/" in name or "/node_modules/" in name or "/runtime-data/" in name for name in names))
            self.assertNotIn(b"-----BEGIN PRIVATE KEY-----", b"\n".join(regular_payloads))


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