"""Tests for scripts/generate.py — E2E song generation and RPP validator."""

from __future__ import annotations

import subprocess
import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).parents[1]))


class TestGenerateCLI:
    """Smoke and integration tests for the generate.py CLI."""

    def test_generate_cli_smoke(self, tmp_path):
        """CLI produces a non-empty .rpp file at the expected path."""
        output = tmp_path / "song.rpp"
        result = subprocess.run(
            [
                sys.executable,
                "scripts/generate.py",
                "--bpm", "95",
                "--key", "Am",
                "--output", str(output),
                "--seed", "42",
            ],
            capture_output=True,
            text=True,
            timeout=60,
        )
        assert result.returncode == 0, f"stderr: {result.stderr}"
        assert output.exists(), f"File not created: {output}"
        assert output.stat().st_size > 0, "File is empty"

    def test_validate_passes_for_valid_output(self, tmp_path):
        """With --validate, CLI returns 0 when validator sees no errors."""
        output = tmp_path / "song.rpp"
        result = subprocess.run(
            [
                sys.executable,
                "scripts/generate.py",
                "--bpm", "95",
                "--key", "Am",
                "--output", str(output),
                "--seed", "42",
                "--validate",
            ],
            capture_output=True,
            text=True,
            timeout=60,
        )
        assert result.returncode == 0, f"stderr: {result.stderr}\nstdout: {result.stdout}"

    def test_validate_detects_track_count_violation(self, tmp_path):
        """Validator flags a project with fewer than 9 tracks."""
        from src.validator.rpp_validator import validate_rpp_output

        rpp_path = tmp_path / "bad.rpp"
        # Write a minimal .rpp with only 5 <TRACK> blocks
        content = (
            "<REAPER_PROJECT 0.1 \"7.65/win64\" 0 0\n"
            + "  <TRACK\n  NAME \"t1\"\n>\n"
            + "  <TRACK\n  NAME \"t2\"\n>\n"
            + "  <TRACK\n  NAME \"t3\"\n>\n"
            + "  <TRACK\n  NAME \"t4\"\n>\n"
            + "  <TRACK\n  NAME \"t5\"\n>\n"
            + ">"
        )
        rpp_path.write_text(content, encoding="utf-8")
        errors = validate_rpp_output(str(rpp_path))
        assert any("Expected 9" in e for e in errors), f"Got: {errors}"

    def test_reproducibility_same_seed(self, tmp_path):
        """Two runs with the same seed produce byte-identical output."""
        output_a = tmp_path / "song_a.rpp"
        output_b = tmp_path / "song_b.rpp"
        for out_path in (output_a, output_b):
            result = subprocess.run(
                [
                    sys.executable,
                    "scripts/generate.py",
                    "--bpm", "95",
                    "--key", "Am",
                    "--output", str(out_path),
                    "--seed", "42",
                ],
                capture_output=True,
                text=True,
                timeout=60,
            )
            assert result.returncode == 0, f"stderr: {result.stderr}"

        assert output_a.read_bytes() == output_b.read_bytes(), (
            "Outputs differ — seed does not guarantee reproducibility"
        )