#!/usr/bin/env python3
import hashlib
import json
import os
import subprocess
import tarfile
import tempfile
import unittest
from pathlib import Path


SCRIPT_DIR = Path(__file__).resolve().parent
BUILDER = SCRIPT_DIR / "build-external-data-plane-artifact.mjs"
EXPECTED_ENTRIES = [
    "platform/docker-compose.external-data-plane.yml",
    "platform/services/external-data-plane",
    "platform/packages/external-provider-contract/package.json",
    "platform/packages/external-provider-contract/src/contract-version.mjs",
    "platform/packages/external-provider-contract/src/data-plane.mjs",
    "platform/packages/external-provider-contract/src/data-product.mjs",
    "platform/packages/external-provider-contract/src/geometry.mjs",
    "platform/packages/external-provider-contract/src/intake-batch.mjs",
    "platform/packages/external-provider-contract/src/index.mjs",
    "platform/packages/external-provider-contract/src/provider-capability-catalog.mjs",
    "platform/packages/external-provider-contract/src/provider-package.mjs",
    "platform/packages/external-provider-contract/src/sensitive-field-policy.mjs",
    "platform/packages/external-provider-contract/src/telemetry-readings.mjs",
    "platform/packages/external-provider-contract/src/zone-source.mjs",
    "platform/packages/external-provider-contract/providers/gelios",
]


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

    def test_artifact_is_runtime_only_public_trust_and_deterministic(self):
        with tempfile.TemporaryDirectory(prefix="nodedc-edp-artifact-") as directory:
            artifact_dir = Path(directory)
            first = self.build(artifact_dir, "edp-managed-publish-unit-001")
            artifact = Path(first["artifact"])
            first_bytes = artifact.read_bytes()
            second = self.build(artifact_dir, "edp-managed-publish-unit-001")
            second_bytes = Path(second["artifact"]).read_bytes()

            self.assertEqual(first["entries"], EXPECTED_ENTRIES)
            self.assertEqual(first["sha256"], hashlib.sha256(first_bytes).hexdigest())
            self.assertEqual(first["sha256"], second["sha256"])
            self.assertEqual(first_bytes, second_bytes)

            with tarfile.open(artifact, "r:gz") as archive:
                members = archive.getmembers()
                names = {member.name for member in members}
                files = archive.extractfile("files.txt").read().decode("utf-8").splitlines()
                manifest = archive.extractfile("manifest.env").read().decode("utf-8")
                compose = archive.extractfile(
                    "payload/platform/docker-compose.external-data-plane.yml"
                ).read().decode("utf-8")
                regular_payloads = [
                    archive.extractfile(member).read()
                    for member in members
                    if member.isfile()
                ]

            self.assertEqual(files, EXPECTED_ENTRIES)
            self.assertEqual(
                manifest,
                "id=edp-managed-publish-unit-001\ncomponent=platform\ntype=app-overlay\n",
            )
            self.assertFalse(any(
                name.startswith("payload/platform/services/external-data-plane/test/")
                or "/node_modules/" in name
                or Path(name).name.startswith(".env")
                or Path(name).name == "private-key.pem"
                for name in names
            ))
            self.assertIn(
                "source: /volume1/docker/nodedc-platform/trust/engine-managed-provisioner",
                compose,
            )
            self.assertIn(
                "source: /volume1/docker/nodedc-platform/trust/foundry-managed-provisioner",
                compose,
            )
            self.assertIn(
                "EXTERNAL_DATA_PLANE_FOUNDRY_PROVISIONER_PUBLIC_KEY_FILE: /run/nodedc-trust/foundry-managed-provisioner/public-key.pem",
                compose,
            )
            self.assertNotIn("private-key.pem", compose)
            self.assertNotIn(b"-----BEGIN PRIVATE KEY-----", b"\n".join(regular_payloads))
            self.assertIn(
                "payload/platform/packages/external-provider-contract/src/provider-capability-catalog.mjs",
                names,
            )
            self.assertIn(
                "payload/platform/packages/external-provider-contract/providers/gelios/capability-catalog-v1.mjs",
                names,
            )


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