"""The serving index names only engine profiles the London seats serve."""
import importlib.util
import pathlib
import unittest

SPEC = importlib.util.spec_from_file_location(
    "r2_catalog_mirror", pathlib.Path(__file__).with_name("r2-catalog-mirror.py"))
MIRROR = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MIRROR)


def entry(base_id, engine, **extra):
    data = {"baseId": base_id, "engine": engine,
            "playedReplaySha1": "b" * 40, "mapContentSha1": "c" * 40,
            "mapPath": "Maps\\FrozenThrone\\(4)TurtleRock.w3x",
            "classicGameMode": "tft", "family": "TFT", "players": ["a", "b"],
            "durationMs": 1000}
    data.update(extra)
    return data


class EngineProfileTests(unittest.TestCase):
    def test_layer_base_names_the_london_profile(self):
        self.assertEqual("native-1120", MIRROR.engine_profile(
            entry("classic-1120-tft-open1-audio-v1", "1.12")))
        self.assertEqual("native-121b", MIRROR.engine_profile(
            entry("classic-121b-tft-open1-audio-v1", "1.21b")))
        self.assertEqual("native-1260", MIRROR.engine_profile(
            entry("classic-1260-tft-open1-audio-v1", "1.26")))
        self.assertEqual("native-124cde", MIRROR.engine_profile(
            entry("classic-124cde-roc-open1-audio-v1", "1.24")))
        self.assertEqual("native-1311-d3d9", MIRROR.engine_profile(
            entry("classic-1311-tft-native-v2", "1.31.1")))
        self.assertEqual("native-1285", MIRROR.engine_profile(
            entry("classic-1285-tft-open1-audio-v7", "1.28.5")))

    def test_engine_string_is_the_fallback_without_a_base(self):
        self.assertEqual("native-1285", MIRROR.engine_profile(entry("", "1.28.5")))
        self.assertEqual("native-1140", MIRROR.engine_profile(entry("", "1.14")))

    def test_engines_london_lacks_yield_no_profile(self):
        for base, engine in (("classic-1290-tft-open1-audio-v1", "1.29"),
                             ("classic-127b-tft-open1-audio-v1", "1.27b"),
                             ("", "1.29")):
            self.assertEqual("", MIRROR.engine_profile(entry(base, engine)), engine)


class CompactIndexTests(unittest.TestCase):
    def test_unsupported_engines_are_skipped_and_counted(self):
        layer = {"schema": 2, "replays": {
            "a" * 40: entry("classic-1120-tft-open1-audio-v1", "1.12"),
            "d" * 40: entry("classic-1290-tft-open1-audio-v1", "1.29"),
            "e" * 40: entry("classic-1290-tft-open1-audio-v1", "1.29"),
        }}
        compact = MIRROR.compact_index(layer)
        self.assertEqual(1, compact["replayCount"])
        self.assertEqual({"1.29": 2}, compact["skipped"])
        self.assertEqual("native-1120", compact["replays"]["a" * 40]["profile"])
        self.assertEqual(3, compact["schema"])

    def test_profile_allowlist_is_a_parameter(self):
        layer = {"schema": 2, "replays": {
            "a" * 40: entry("classic-1120-tft-open1-audio-v1", "1.12")}}
        compact = MIRROR.compact_index(layer, profiles={"native-1285"})
        self.assertEqual(0, compact["replayCount"])
        self.assertEqual({"1.12": 1}, compact["skipped"])

    def test_overrides_replace_the_base_profile_and_are_counted(self):
        # Raw version 24 is ambiguous: the 2009 events were recorded on
        # 1.24a/b but the pipeline only has a 1.24c/d/e base.
        layer = {"schema": 2, "replays": {
            "a" * 40: entry("classic-124cde-tft-open1-audio-v1", "1.24"),
            "b" * 40: entry("classic-124cde-tft-open1-audio-v1", "1.24"),
        }}
        compact = MIRROR.compact_index(layer, overrides={"a" * 40: "native-124ab"})
        self.assertEqual("native-124ab", compact["replays"]["a" * 40]["profile"])
        self.assertEqual("native-124cde", compact["replays"]["b" * 40]["profile"])
        self.assertEqual({"native-124ab": 1}, compact["overridden"])
        self.assertEqual({}, MIRROR.compact_index(layer)["overridden"])

    def test_override_file_is_validated(self):
        import json
        import tempfile
        with tempfile.TemporaryDirectory() as tmp:
            path = pathlib.Path(tmp) / "overrides.json"
            path.write_text(json.dumps({"schema": 1, "overrides": {
                "A" * 40: "native-124ab"}}))
            self.assertEqual({"a" * 40: "native-124ab"},
                             MIRROR.load_profile_overrides(path))
            for bad in ({"schema": 2, "overrides": {}},
                        {"schema": 1, "overrides": {"a" * 40: "native-1290"}},
                        {"schema": 1, "overrides": {"abc": "native-124ab"}}):
                path.write_text(json.dumps(bad))
                with self.assertRaises(ValueError):
                    MIRROR.load_profile_overrides(path)

    def test_committed_override_file_loads(self):
        overrides = MIRROR.load_profile_overrides(
            pathlib.Path(MIRROR.__file__).with_name("serving-profile-overrides.json"))
        self.assertTrue(overrides)
        self.assertEqual({"native-124ab"}, set(overrides.values()))


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