"""Tests for slash command parsing."""

import pytest

from fwauto.slash_commands import (
    SlashCommand,
    _parse_build_args,
    _parse_deploy_args,
    _parse_log_args,
    parse_command_args,
    parse_slash_command,
)


class TestParseSlashCommand:
    """Test slash command parsing."""

    def test_parse_build_command(self):
        cmd = parse_slash_command("/build")
        assert cmd is not None
        assert cmd.name == "build"
        assert cmd.raw_args == []

    def test_parse_deploy_with_binary_args(self):
        cmd = parse_slash_command("/deploy --binary-args test.hex")
        assert cmd is not None
        assert cmd.name == "deploy"
        assert cmd.raw_args == ["--binary-args", "test.hex"]

    def test_parse_deploy_with_scenario(self):
        cmd = parse_slash_command("/deploy --scenario quick")
        assert cmd is not None
        assert cmd.name == "deploy"
        assert cmd.raw_args == ["--scenario", "quick"]

    def test_parse_log_with_prompt(self):
        cmd = parse_slash_command("/log uart.log '有任何 error 嗎?'")
        assert cmd is not None
        assert cmd.name == "log"
        assert cmd.raw_args == ["uart.log", "有任何 error 嗎?"]

    def test_parse_natural_language_returns_none(self):
        cmd = parse_slash_command("請幫我分析這個錯誤")
        assert cmd is None

    def test_parse_invalid_command_returns_none(self):
        cmd = parse_slash_command("/invalid_cmd")
        assert cmd is None

    def test_parse_empty_slash_returns_none(self):
        cmd = parse_slash_command("/")
        assert cmd is None

    def test_parse_with_invalid_quotes_returns_none(self):
        cmd = parse_slash_command("/log 'unclosed quote")
        assert cmd is None


class TestParseBuildArgs:
    """Test build command argument parsing."""

    def test_build_no_args(self):
        args = _parse_build_args([])
        assert args == {}

    def test_build_ignores_extra_args(self):
        # Build currently has no arguments, so extra args are ignored
        args = _parse_build_args(["--unknown", "value"])
        assert args == {}


class TestParseDeployArgs:
    """Test deploy command argument parsing."""

    def test_deploy_binary_args_long(self):
        args = _parse_deploy_args(["--binary-args", "test.hex"])
        assert args["binary_args"] == "test.hex"

    def test_deploy_binary_args_short(self):
        args = _parse_deploy_args(["-ba", "on"])
        assert args["binary_args"] == "on"

    def test_deploy_scenario_long(self):
        args = _parse_deploy_args(["--scenario", "quick"])
        assert "scenario" in args
        assert args["scenario"] == "quick"

    def test_deploy_scenario_short(self):
        args = _parse_deploy_args(["-s", "test-mode"])
        assert "scenario" in args
        assert args["scenario"] == "test-mode"

    def test_deploy_binary_args_priority(self):
        # --binary-args takes priority over --scenario
        args = _parse_deploy_args(["--binary-args", "direct.hex", "--scenario", "quick"])
        assert args["binary_args"] == "direct.hex"
        # Scenario should not be in result when binary_args is provided
        assert "scenario" not in args

    def test_deploy_no_args(self):
        args = _parse_deploy_args([])
        assert args["binary_args"] == ""

    def test_deploy_binary_args_missing_value(self):
        with pytest.raises(ValueError, match="--binary-args requires a value"):
            _parse_deploy_args(["--binary-args"])

    def test_deploy_scenario_missing_value(self):
        with pytest.raises(ValueError, match="--scenario requires a value"):
            _parse_deploy_args(["--scenario"])


class TestParseLogArgs:
    """Test log command argument parsing."""

    def test_log_path_only(self):
        args = _parse_log_args(["uart.log"])
        assert args["log_path"] == "uart.log"
        assert args["analysis_prompt"] == "分析這份 log"

    def test_log_path_with_prompt(self):
        args = _parse_log_args(["uart.log", "有任何 error 嗎?"])
        assert args["log_path"] == "uart.log"
        assert args["analysis_prompt"] == "有任何 error 嗎?"

    def test_log_path_with_multi_word_prompt(self):
        args = _parse_log_args(["uart.log", "請", "分析", "這個", "log"])
        assert args["log_path"] == "uart.log"
        assert args["analysis_prompt"] == "請 分析 這個 log"

    def test_log_empty_args_uses_defaults(self):
        """Test that empty args returns default values (auto-detect log path from config)."""
        args = _parse_log_args([])
        assert args["log_path"] is None  # Will be auto-detected from config
        assert args["analysis_prompt"] == "分析這份 log"


class TestParseCommandArgs:
    """Test high-level command_args parsing."""

    def test_parse_build_command_args(self):
        cmd = SlashCommand(name="build", raw_args=[], parsed_args={})
        args = parse_command_args(cmd)
        assert args == {}

    def test_parse_deploy_command_args(self):
        cmd = SlashCommand(name="deploy", raw_args=["--binary-args", "test.hex"], parsed_args={})
        args = parse_command_args(cmd)
        assert args["binary_args"] == "test.hex"

    def test_parse_log_command_args(self):
        cmd = SlashCommand(name="log", raw_args=["uart.log", "有 error 嗎?"], parsed_args={})
        args = parse_command_args(cmd)
        assert args["log_path"] == "uart.log"
        assert args["analysis_prompt"] == "有 error 嗎?"

    def test_parse_unknown_command(self):
        cmd = SlashCommand(name="unknown", raw_args=[], parsed_args={})
        with pytest.raises(ValueError, match="Unknown command"):
            parse_command_args(cmd)
