from __future__ import annotations

import json
import pathlib
import unittest

from meridian_euid import is_valid, validate


def _repo_root() -> pathlib.Path:
    here = pathlib.Path(__file__).resolve()
    # reference-implementations/python/tests/test_vectors.py
    return here.parents[3]


class TestVectorsV2(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        vectors_path = _repo_root() / "test-vectors" / "v2.json"
        cls.vectors_path = vectors_path
        cls.vectors = json.loads(vectors_path.read_text(encoding="utf-8"))

    def test_valid_production(self) -> None:
        for item in self.vectors["valid_production"]:
            euid = item["euid"]
            expected = item.get("canonical", euid.upper())
            self.assertEqual(validate(euid, environment="production"), expected)
            self.assertTrue(is_valid(euid, environment="production"))

    def test_valid_sandbox(self) -> None:
        for item in self.vectors["valid_sandbox"]:
            euid = item["euid"]
            allowed = set(item.get("allowed_sandbox_prefixes", [])) or None
            expected = item.get("canonical", euid.upper())
            self.assertEqual(
                validate(euid, environment="sandbox", allowed_sandbox_prefixes=allowed),
                expected,
            )
            self.assertTrue(
                is_valid(euid, environment="sandbox", allowed_sandbox_prefixes=allowed)
            )

    def test_invalid(self) -> None:
        for item in self.vectors["invalid"]:
            euid = item["euid"]
            context = item["context"]
            env = context["environment"]
            allowed = set(context.get("allowed_sandbox_prefixes", [])) or None
            with self.assertRaises(Exception, msg=f"expected invalid: {item}"):
                validate(euid, environment=env, allowed_sandbox_prefixes=allowed)


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