import hashlib
import importlib.util
import json
import tempfile
import unittest
from pathlib import Path


MODULE_PATH = Path(__file__).with_name("stage-replay-session.py")
SPEC = importlib.util.spec_from_file_location("stage_replay_session", MODULE_PATH)
MODULE = importlib.util.module_from_spec(SPEC)
assert SPEC.loader
SPEC.loader.exec_module(MODULE)


class StageReplaySessionTests(unittest.TestCase):
    def test_stages_verified_replay_and_map_aliases(self):
        with tempfile.TemporaryDirectory() as directory:
            root = Path(directory)
            replay = root / "game.w3g"
            replay.write_bytes(b"replay")
            maps = root / "maps"
            maps.mkdir()
            map_file = maps / "map.w3x"
            map_file.write_bytes(b"exact-map")
            metadata = root / "game.json"
            metadata.write_text(json.dumps({
                "engineProfile": "native-124cde",
                "replaySha1": hashlib.sha1(b"replay").hexdigest(),
                "mapPath": "Maps\\League\\Arena.w3x",
                "mapFile": "maps/map.w3x",
                "mapContentSha1": hashlib.sha1(b"exact-map").hexdigest(),
            }))
            prefix = root / "prefix"
            game = root / "session-game"
            game.mkdir()
            result = MODULE.stage(metadata, replay, prefix, game)
            self.assertTrue(result["mapInstalled"])
            documents = prefix / "drive_c/users/ubuntu/Documents/Warcraft III"
            for target in (
                documents / "Maps/League/Arena.w3x",
                documents / "Maps/Arena.w3x",
                documents / "Maps/download/Arena.w3x",
                game / "Maps/League/Arena.w3x",
            ):
                self.assertEqual(b"exact-map", target.read_bytes())

    def test_rejects_map_escape(self):
        with self.assertRaises(ValueError):
            MODULE.map_parts("Maps\\..\\escape.w3x")

    def test_expired_patch_map_is_114_only(self):
        self.assertEqual(["Maps", "ExpiredPatchMap.tmp"],
                         MODULE.map_parts("Maps\\ExpiredPatchMap.tmp", True))
        with self.assertRaises(ValueError):
            MODULE.map_parts("Maps\\ExpiredPatchMap.tmp")

    def test_new_client_uses_singular_replay_directory(self):
        with tempfile.TemporaryDirectory() as directory:
            root = Path(directory)
            replay = root / "new.w3g"
            replay.write_bytes(b"new-client-replay")
            metadata = root / "new.json"
            metadata.write_text(json.dumps({
                "engineProfile": "native-1311-d3d9",
                "replaySha1": hashlib.sha1(b"new-client-replay").hexdigest(),
            }))
            prefix = root / "prefix"
            game = root / "game"
            game.mkdir()
            MODULE.stage(metadata, replay, prefix, game, "Replay")
            target = (prefix / "drive_c/users/ubuntu/Documents/Warcraft III" /
                      "Replay/trace.w3g")
            self.assertEqual(b"new-client-replay", target.read_bytes())


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