"""Tests for CLI subcommand resolution via Vidhi."""

import sys
from unittest.mock import patch

from vidhi import parse_cli_args

from smriti.config import (
    Auto,
    AutoDir,
    Claude,
    ClaudeAuto,
    ClaudeAutoDir,
    ClaudeKill,
    ClaudeKillAll,
    ClaudeList,
    ClaudeListDir,
    ClaudeReattach,
    Create,
    Env,
    Kill,
    KillAll,
    KillLatest,
    ListAll,
    ListDir,
    Reattach,
    SmritiCommand,
)


def test_default_is_create():
    """No subcommand should default to Create."""
    with patch.object(sys, "argv", ["sm"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Create)


def test_explicit_create():
    """Explicit 'create' subcommand."""
    with patch.object(sys, "argv", ["sm", "create", "--tag", "dev"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Create)
    assert cmd.tag == "dev"


def test_reattach_alias():
    """Short alias 'r' should resolve to Reattach."""
    with patch.object(sys, "argv", ["sm", "r"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Reattach)


def test_reattach_has_no_target():
    """Reattach should not accept --target (moved to auto)."""
    with patch.object(sys, "argv", ["sm", "r"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Reattach)
    assert not hasattr(cmd, "target")


def test_list_alias():
    """Short alias 'l' should resolve to ListAll."""
    with patch.object(sys, "argv", ["sm", "l"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ListAll)


def test_list_dir_alias():
    """Short alias 'ld' should resolve to ListDir."""
    with patch.object(sys, "argv", ["sm", "ld"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ListDir)


def test_claude_alias():
    """Short alias 'cc' should resolve to Claude."""
    with patch.object(sys, "argv", ["sm", "cc"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Claude)


def test_claude_with_args():
    """Claude subcommand with --args flag."""
    with patch.object(sys, "argv", ["sm", "cc", "--args", "--resume"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Claude)
    assert cmd.args == "--resume"


def test_claude_auto_alias():
    with patch.object(sys, "argv", ["sm", "cca"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeAuto)


def test_claude_list_alias():
    with patch.object(sys, "argv", ["sm", "ccl"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeList)


def test_kill_alias():
    with patch.object(sys, "argv", ["sm", "k"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Kill)


def test_kill_all_alias():
    with patch.object(sys, "argv", ["sm", "ka"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, KillAll)


def test_kill_latest_alias():
    with patch.object(sys, "argv", ["sm", "kl"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, KillLatest)


def test_env_alias():
    with patch.object(sys, "argv", ["sm", "e"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Env)


def test_shared_no_conda_flag():
    """Base class field --no_conda should work on any subcommand."""
    with patch.object(sys, "argv", ["sm", "cc", "--no_conda", "true"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Claude)
    assert cmd.no_conda is True


def test_long_names_work():
    """Full subcommand names should work."""
    with patch.object(sys, "argv", ["sm", "reattach"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Reattach)

    with patch.object(sys, "argv", ["sm", "claude"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Claude)

    with patch.object(sys, "argv", ["sm", "list-dir"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ListDir)


def test_auto_alias():
    """Short alias 'a' should resolve to Auto."""
    with patch.object(sys, "argv", ["sm", "a"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Auto)


def test_auto_with_target():
    """Auto should accept --target flag."""
    with patch.object(sys, "argv", ["sm", "a", "--target", "vajra"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Auto)
    assert cmd.target == "vajra"


def test_auto_target_default_none():
    """Auto target should default to None."""
    with patch.object(sys, "argv", ["sm", "a"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Auto)
    assert cmd.target is None


def test_default_command_with_flags():
    """Flags without subcommand name should use default (Create)."""
    with patch.object(sys, "argv", ["sm", "--tag", "debug"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, Create)
    assert cmd.tag == "debug"


# --- New subcommand tests ---


def test_auto_dir_alias():
    """Short alias 'ad' should resolve to AutoDir."""
    with patch.object(sys, "argv", ["sm", "ad"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, AutoDir)


def test_auto_dir_long_name():
    """Full name 'auto-dir' should resolve to AutoDir."""
    with patch.object(sys, "argv", ["sm", "auto-dir"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, AutoDir)


def test_claude_auto_dir_alias():
    """Short alias 'ccad' should resolve to ClaudeAutoDir."""
    with patch.object(sys, "argv", ["sm", "ccad"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeAutoDir)


def test_claude_auto_dir_long_name():
    """Full name 'claude-auto-dir' should resolve to ClaudeAutoDir."""
    with patch.object(sys, "argv", ["sm", "claude-auto-dir"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeAutoDir)


def test_claude_auto_dir_with_config():
    """ClaudeAutoDir should accept --config_dir flag."""
    with patch.object(sys, "argv", ["sm", "ccad", "--config_dir", "~/.sclaude"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeAutoDir)
    assert cmd.config_dir == "~/.sclaude"


def test_claude_reattach_alias():
    """Short alias 'ccr' should resolve to ClaudeReattach."""
    with patch.object(sys, "argv", ["sm", "ccr"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeReattach)


def test_claude_reattach_long_name():
    """Full name 'claude-reattach' should resolve to ClaudeReattach."""
    with patch.object(sys, "argv", ["sm", "claude-reattach"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeReattach)


def test_claude_list_dir_alias():
    """Short alias 'ccld' should resolve to ClaudeListDir."""
    with patch.object(sys, "argv", ["sm", "ccld"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeListDir)


def test_claude_list_dir_long_name():
    """Full name 'claude-list-dir' should resolve to ClaudeListDir."""
    with patch.object(sys, "argv", ["sm", "claude-list-dir"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeListDir)


def test_claude_kill_alias():
    """Short alias 'cck' should resolve to ClaudeKill."""
    with patch.object(sys, "argv", ["sm", "cck"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeKill)


def test_claude_kill_long_name():
    """Full name 'claude-kill' should resolve to ClaudeKill."""
    with patch.object(sys, "argv", ["sm", "claude-kill"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeKill)


def test_claude_kill_all_alias():
    """Short alias 'ccka' should resolve to ClaudeKillAll."""
    with patch.object(sys, "argv", ["sm", "ccka"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeKillAll)


def test_claude_kill_all_long_name():
    """Full name 'claude-kill-all' should resolve to ClaudeKillAll."""
    with patch.object(sys, "argv", ["sm", "claude-kill-all"]):
        cmd = parse_cli_args(SmritiCommand)
    assert isinstance(cmd, ClaudeKillAll)
