"""Tests for scripts/compose.py render CLI flags."""

import sys
from pathlib import Path

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

import pytest
import argparse
from unittest.mock import patch, MagicMock
from scripts.compose import main as compose_main


class TestRenderFlag:
    """Test --render and --render-output CLI arguments."""

    def test_render_flag_defaults_to_false(self):
        """Without --render, the render flag should be False."""
        parser = argparse.ArgumentParser()
        parser.add_argument("--render", action="store_true")
        parser.add_argument("--render-output", default=None)

        args = parser.parse_args([])
        assert args.render is False

    def test_render_flag_true_when_provided(self):
        """With --render, the flag should be True."""
        parser = argparse.ArgumentParser()
        parser.add_argument("--render", action="store_true")
        parser.add_argument("--render-output", default=None)

        args = parser.parse_args(["--render"])
        assert args.render is True

    def test_render_output_defaults_to_none(self):
        """--render-output defaults to None when not provided."""
        parser = argparse.ArgumentParser()
        parser.add_argument("--render", action="store_true")
        parser.add_argument("--render-output", default=None)

        args = parser.parse_args([])
        assert args.render_output is None

    @patch("scripts.compose.render_project")
    @patch("scripts.compose.RPPBuilder")
    def test_render_triggers_render_project_call(self, mock_builder_cls, mock_render):
        """Calling main with --render invokes render_project."""
        mock_builder = MagicMock()
        mock_builder_cls.return_value = mock_builder

        with patch("scripts.compose.SampleSelector") as mock_selector:
            mock_sel_instance = MagicMock()
            mock_sel_instance.select_one.return_value = None
            mock_selector.return_value = mock_sel_instance

            with patch("sys.argv", ["compose.py", "--genre", "reggaeton", "--render"]):
                compose_main()

        mock_render.assert_called_once()
        call_args = mock_render.call_args
        # First arg should be the .rpp path, second should be .wav path
        rpp_path = call_args[0][0]
        wav_path = call_args[0][1]
        assert rpp_path.endswith(".rpp")
        assert wav_path.endswith(".wav")

    @patch("scripts.compose.render_project")
    @patch("scripts.compose.RPPBuilder")
    def test_without_render_does_not_call_render_project(self, mock_builder_cls, mock_render):
        """Calling main without --render does NOT invoke render_project."""
        mock_builder = MagicMock()
        mock_builder_cls.return_value = mock_builder

        with patch("scripts.compose.SampleSelector") as mock_selector:
            mock_sel_instance = MagicMock()
            mock_sel_instance.select_one.return_value = None
            mock_selector.return_value = mock_sel_instance

            with patch("sys.argv", ["compose.py", "--genre", "reggaeton"]):
                compose_main()

        mock_render.assert_not_called()

    @patch("scripts.compose.render_project")
    @patch("scripts.compose.RPPBuilder")
    def test_render_output_overrides_default_wav_path(self, mock_builder_cls, mock_render):
        """--render-output sets the WAV path explicitly."""
        mock_builder = MagicMock()
        mock_builder_cls.return_value = mock_builder

        with patch("scripts.compose.SampleSelector") as mock_selector:
            mock_sel_instance = MagicMock()
            mock_sel_instance.select_one.return_value = None
            mock_selector.return_value = mock_sel_instance

            with patch("sys.argv", [
                "compose.py",
                "--genre", "reggaeton",
                "--render",
                "--render-output", "output/my_render.wav"
            ]):
                compose_main()

        mock_render.assert_called_once()
        wav_path = mock_render.call_args[0][1]
        assert wav_path == "output/my_render.wav"

    @patch("scripts.compose.render_project")
    @patch("scripts.compose.RPPBuilder")
    def test_render_project_propagates_file_not_found_error(self, mock_builder_cls, mock_render):
        """FileNotFoundError from render_project is propagated to caller."""
        mock_builder = MagicMock()
        mock_builder_cls.return_value = mock_builder
        mock_render.side_effect = FileNotFoundError("reaper.exe not found")

        with patch("scripts.compose.SampleSelector") as mock_selector:
            mock_sel_instance = MagicMock()
            mock_sel_instance.select_one.return_value = None
            mock_selector.return_value = mock_sel_instance

            with patch("sys.argv", [
                "compose.py",
                "--genre", "reggaeton",
                "--render",
            ]):
                with pytest.raises(FileNotFoundError):
                    compose_main()