"""Tests for the worker normalize module."""

import json
import tempfile
from pathlib import Path

import zstandard as zstd


class TestNormalizeBundle:
    """Tests for bundle normalization."""

    def _create_compressed_jsonl(self, path: Path, records: list):
        """Helper to create a compressed JSONL file."""
        compressor = zstd.ZstdCompressor(level=3)
        with open(path, "wb") as f:
            writer = compressor.stream_writer(f)
            for record in records:
                line = json.dumps(record, separators=(",", ":")).encode("utf-8")
                writer.write(line + b"\n")
            writer.flush(zstd.FLUSH_FRAME)
            writer.close()

    def test_normalize_decompresses_files(self):
        """Test that normalize decompresses zstd files to plain JSONL."""
        from worker.normalize import normalize_bundle

        with tempfile.TemporaryDirectory() as tmpdir:
            input_dir = Path(tmpdir) / "input"
            output_dir = Path(tmpdir) / "output"
            input_dir.mkdir()
            output_dir.mkdir()

            # Create compressed input
            records = [
                {"seq": 1, "type": "HTTP", "url": "http://example.com"},
                {"seq": 2, "type": "HTTP", "url": "http://example.org"},
            ]
            self._create_compressed_jsonl(input_dir / "deps_http.jsonl.zst", records)

            # Create manifest
            (input_dir / "manifest.json").write_text('{"version": 1}')

            normalize_bundle(input_dir, output_dir, ["manifest.json", "deps_http.jsonl.zst"])

            # Check output is decompressed
            assert (output_dir / "deps_http.jsonl").exists()
            content = (output_dir / "deps_http.jsonl").read_text()
            lines = content.strip().split("\n")
            assert len(lines) == 2
            assert json.loads(lines[0])["url"] == "http://example.com"

    def test_normalize_copies_manifest(self):
        """Test that manifest.json is copied without modification."""
        from worker.normalize import normalize_bundle

        with tempfile.TemporaryDirectory() as tmpdir:
            input_dir = Path(tmpdir) / "input"
            output_dir = Path(tmpdir) / "output"
            input_dir.mkdir()
            output_dir.mkdir()

            manifest = {"version": 1, "run_id": "test-123"}
            (input_dir / "manifest.json").write_text(json.dumps(manifest))

            normalize_bundle(input_dir, output_dir, ["manifest.json"])

            assert (output_dir / "manifest.json").exists()
            result = json.loads((output_dir / "manifest.json").read_text())
            assert result == manifest

    def test_normalize_handles_empty_files(self):
        """Test that empty compressed files are handled."""
        from worker.normalize import normalize_bundle

        with tempfile.TemporaryDirectory() as tmpdir:
            input_dir = Path(tmpdir) / "input"
            output_dir = Path(tmpdir) / "output"
            input_dir.mkdir()
            output_dir.mkdir()

            # Create empty compressed file
            self._create_compressed_jsonl(input_dir / "deps_sql.jsonl.zst", [])
            (input_dir / "manifest.json").write_text('{"version": 1}')

            normalize_bundle(input_dir, output_dir, ["manifest.json", "deps_sql.jsonl.zst"])

            assert (output_dir / "deps_sql.jsonl").exists()
            content = (output_dir / "deps_sql.jsonl").read_text()
            assert content.strip() == ""

    def test_normalize_preserves_record_order(self):
        """Test that record order is preserved during normalization."""
        from worker.normalize import normalize_bundle

        with tempfile.TemporaryDirectory() as tmpdir:
            input_dir = Path(tmpdir) / "input"
            output_dir = Path(tmpdir) / "output"
            input_dir.mkdir()
            output_dir.mkdir()

            records = [{"seq": i, "data": f"record_{i}"} for i in range(100)]
            self._create_compressed_jsonl(input_dir / "events.jsonl.zst", records)
            (input_dir / "manifest.json").write_text('{"version": 1}')

            normalize_bundle(input_dir, output_dir, ["manifest.json", "events.jsonl.zst"])

            content = (output_dir / "events.jsonl").read_text()
            lines = content.strip().split("\n")
            for i, line in enumerate(lines):
                assert json.loads(line)["seq"] == i


class TestBuildHarness:
    """Tests for harness building."""

    def test_build_harness_creates_tarball(self):
        """Test that build_harness creates a valid tarball."""
        import tarfile

        from worker.harness import build_harness

        with tempfile.TemporaryDirectory() as tmpdir:
            input_dir = Path(tmpdir) / "input"
            input_dir.mkdir()

            # Create minimal input files
            (input_dir / "manifest.json").write_text('{"version": 1}')
            (input_dir / "deps_http.jsonl").write_text('{"type": "HTTP"}\n')

            output_tar = Path(tmpdir) / "harness.tar.gz"
            build_harness(input_dir, output_tar)

            assert output_tar.exists()
            assert tarfile.is_tarfile(output_tar)

    def test_build_harness_includes_replay_module(self):
        """Test that harness includes the autodebug_replay module."""
        import tarfile

        from worker.harness import build_harness

        with tempfile.TemporaryDirectory() as tmpdir:
            input_dir = Path(tmpdir) / "input"
            input_dir.mkdir()

            (input_dir / "manifest.json").write_text('{"version": 1}')

            output_tar = Path(tmpdir) / "harness.tar.gz"
            build_harness(input_dir, output_tar)

            with tarfile.open(output_tar, "r:gz") as tar:
                names = tar.getnames()
                # Check autodebug_replay is included
                assert any("autodebug_replay" in name for name in names)
                # Check transcripts are included
                assert any("transcripts" in name for name in names)

    def test_build_harness_includes_dockerfile(self):
        """Test that harness includes a Dockerfile."""
        import tarfile

        from worker.harness import build_harness

        with tempfile.TemporaryDirectory() as tmpdir:
            input_dir = Path(tmpdir) / "input"
            input_dir.mkdir()

            (input_dir / "manifest.json").write_text('{"version": 1}')

            output_tar = Path(tmpdir) / "harness.tar.gz"
            build_harness(input_dir, output_tar)

            with tarfile.open(output_tar, "r:gz") as tar:
                names = tar.getnames()
                assert any("Dockerfile" in name for name in names)
