#!/usr/bin/python3
"""Tests for sbo_create.cli argument parser."""

import pytest

from sbo_create.cli import parse_args

VERSION = '2.1.0'


def _parse(args: list[str], monkeypatch: pytest.MonkeyPatch):  # type: ignore[no-untyped-def]
    """Helper: patch sys.argv and call parse_args."""
    monkeypatch.setattr('sys.argv', ['sbo-create'] + args)
    return parse_args(VERSION)


# ---------------------------------------------------------------------------
# No arguments — prints help and raises SystemExit(0)
# ---------------------------------------------------------------------------

def test_no_args_raises_systemexit(monkeypatch: pytest.MonkeyPatch) -> None:
    with pytest.raises(SystemExit) as exc_info:
        _parse([], monkeypatch)
    assert exc_info.value.code == 0


# ---------------------------------------------------------------------------
# create subcommand
# ---------------------------------------------------------------------------

def test_create_command(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create'], monkeypatch)
    assert ns.command == 'create'


@pytest.mark.parametrize('flag', ['-n', '--prgnam'])
def test_create_prgnam(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create', flag, 'firefox'], monkeypatch)
    assert ns.prgnam == 'firefox'


@pytest.mark.parametrize('flag', ['-r', '--prg-version'])
def test_create_prg_version(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create', flag, '1.0.0'], monkeypatch)
    assert ns.prg_version == '1.0.0'


@pytest.mark.parametrize('flag', ['-t', '--template'])
@pytest.mark.parametrize('tpl', ['autotools', 'cmake', 'perl', 'python', 'rubygem', 'haskell', 'meson'])
def test_create_template(flag: str, tpl: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create', flag, tpl], monkeypatch)
    assert ns.template == tpl


@pytest.mark.parametrize('flag', ['-a', '--arm64'])
def test_create_arm64(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create', flag], monkeypatch)
    assert ns.arm64 is True


@pytest.mark.parametrize('flag', ['-o', '--output'])
def test_create_output(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create', flag, '/tmp/test'], monkeypatch)
    assert ns.output == '/tmp/test'


@pytest.mark.parametrize('flag', ['-D', '--dry-run'])
def test_create_dry_run(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create', flag], monkeypatch)
    assert ns.dry_run is True


def test_create_combined(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['create', '-n', 'myapp', '-r', '2.0', '-t', 'python', '-a'], monkeypatch)
    assert ns.prgnam == 'myapp'
    assert ns.prg_version == '2.0'
    assert ns.template == 'python'
    assert ns.arm64 is True


# ---------------------------------------------------------------------------
# download subcommand
# ---------------------------------------------------------------------------

def test_download_command(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['download'], monkeypatch)
    assert ns.command == 'download'


# ---------------------------------------------------------------------------
# check subcommand
# ---------------------------------------------------------------------------

def test_check_single_name(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['check', 'vim'], monkeypatch)
    assert ns.names == ['vim']


def test_check_multiple_names(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['check', 'vim', 'emacs', 'firefox'], monkeypatch)
    assert ns.names == ['vim', 'emacs', 'firefox']


# ---------------------------------------------------------------------------
# list subcommand
# ---------------------------------------------------------------------------

def test_list_command(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['list'], monkeypatch)
    assert ns.command == 'list'


# ---------------------------------------------------------------------------
# validate subcommand
# ---------------------------------------------------------------------------

def test_validate_command(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['validate'], monkeypatch)
    assert ns.command == 'validate'


# ---------------------------------------------------------------------------
# bump subcommand
# ---------------------------------------------------------------------------

def test_bump_version(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['bump', '2.0.0'], monkeypatch)
    assert ns.version == '2.0.0'
    assert ns.with_sources is False


@pytest.mark.parametrize('flag', ['-W', '--with-sources'])
def test_bump_with_sources(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['bump', '2.0.0', flag], monkeypatch)
    assert ns.with_sources is True


# ---------------------------------------------------------------------------
# package subcommand
# ---------------------------------------------------------------------------

def test_package_command(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['package'], monkeypatch)
    assert ns.command == 'package'


@pytest.mark.parametrize('flag', ['-o', '--output'])
def test_package_output(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['package', flag, '/tmp/out'], monkeypatch)
    assert ns.output == '/tmp/out'


# ---------------------------------------------------------------------------
# update subcommand
# ---------------------------------------------------------------------------

def test_update_command(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['update'], monkeypatch)
    assert ns.command == 'update'


# ---------------------------------------------------------------------------
# maintainer subcommand
# ---------------------------------------------------------------------------

def test_maintainer_command(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['maintainer'], monkeypatch)
    assert ns.command == 'maintainer'
    assert ns.show is False


@pytest.mark.parametrize('flag', ['-S', '--show'])
def test_maintainer_show(flag: str, monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['maintainer', flag], monkeypatch)
    assert ns.show is True


# ---------------------------------------------------------------------------
# global --no-color option
# ---------------------------------------------------------------------------

def test_no_color_default(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['validate'], monkeypatch)
    assert ns.no_color is False


def test_no_color_before_subcommand(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['--no-color', 'validate'], monkeypatch)
    assert ns.no_color is True


def test_no_color_after_subcommand(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['validate', '--no-color'], monkeypatch)
    assert ns.no_color is True


# ---------------------------------------------------------------------------
# repo subcommand group
# ---------------------------------------------------------------------------

def test_repo_no_subcommand_exits(monkeypatch: pytest.MonkeyPatch) -> None:
    with pytest.raises(SystemExit) as exc_info:
        _parse(['repo'], monkeypatch)
    assert exc_info.value.code == 0


def test_repo_diff(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['repo', 'diff'], monkeypatch)
    assert ns.command == 'repo'
    assert ns.repo_command == 'diff'
    assert ns.unified == 3


def test_repo_diff_unified(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['repo', 'diff', '-U', '5'], monkeypatch)
    assert ns.unified == 5


def test_repo_sync(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['repo', 'sync'], monkeypatch)
    assert ns.command == 'repo'
    assert ns.repo_command == 'sync'


def test_repo_submit(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['repo', 'submit'], monkeypatch)
    assert ns.command == 'repo'
    assert ns.repo_command == 'submit'


def test_repo_copy(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['repo', 'copy'], monkeypatch)
    assert ns.command == 'repo'
    assert ns.repo_command == 'copy'


def test_repo_log(monkeypatch: pytest.MonkeyPatch) -> None:
    ns = _parse(['repo', 'log'], monkeypatch)
    assert ns.command == 'repo'
    assert ns.repo_command == 'log'
