#!/usr/bin/env python3
"""
Tests for CLI Parser System

Tests the modular parser registration system.
"""

import argparse
import pytest

from skill_seekers.cli.parsers import (
    PARSERS,
    SubcommandParser,
    get_parser_names,
    register_parsers,
)
from skill_seekers.cli.parsers.scrape_parser import ScrapeParser
from skill_seekers.cli.parsers.github_parser import GitHubParser
from skill_seekers.cli.parsers.package_parser import PackageParser


class TestParserRegistry:
    """Test parser registry functionality."""

    def test_all_parsers_registered(self):
        """Test that all parsers are registered."""
        assert len(PARSERS) == 21, f"Expected 21 parsers, got {len(PARSERS)}"

    def test_get_parser_names(self):
        """Test getting list of parser names."""
        names = get_parser_names()
        assert len(names) == 21
        assert "scrape" in names
        assert "github" in names
        assert "package" in names
        assert "upload" in names
        assert "analyze" in names
        assert "config" in names
        assert "workflows" in names

    def test_all_parsers_are_subcommand_parsers(self):
        """Test that all parsers inherit from SubcommandParser."""
        for parser in PARSERS:
            assert isinstance(parser, SubcommandParser)

    def test_all_parsers_have_required_properties(self):
        """Test that all parsers have name, help, description."""
        for parser in PARSERS:
            assert hasattr(parser, "name")
            assert hasattr(parser, "help")
            assert hasattr(parser, "description")
            assert isinstance(parser.name, str)
            assert isinstance(parser.help, str)
            assert isinstance(parser.description, str)
            assert len(parser.name) > 0
            assert len(parser.help) > 0

    def test_all_parsers_have_add_arguments_method(self):
        """Test that all parsers implement add_arguments."""
        for parser in PARSERS:
            assert hasattr(parser, "add_arguments")
            assert callable(parser.add_arguments)

    def test_no_duplicate_parser_names(self):
        """Test that all parser names are unique."""
        names = [p.name for p in PARSERS]
        assert len(names) == len(set(names)), "Duplicate parser names found!"


class TestParserCreation:
    """Test parser creation functionality."""

    def test_scrape_parser_creates_subparser(self):
        """Test that ScrapeParser creates valid subparser."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers()

        scrape_parser = ScrapeParser()
        subparser = scrape_parser.create_parser(subparsers)

        assert subparser is not None
        assert scrape_parser.name == "scrape"
        assert scrape_parser.help == "Scrape documentation website"

    def test_github_parser_creates_subparser(self):
        """Test that GitHubParser creates valid subparser."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers()

        github_parser = GitHubParser()
        subparser = github_parser.create_parser(subparsers)

        assert subparser is not None
        assert github_parser.name == "github"

    def test_package_parser_creates_subparser(self):
        """Test that PackageParser creates valid subparser."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers()

        package_parser = PackageParser()
        subparser = package_parser.create_parser(subparsers)

        assert subparser is not None
        assert package_parser.name == "package"

    def test_register_parsers_creates_all_subcommands(self):
        """Test that register_parsers creates all 19 subcommands."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers(dest="command")

        # Register all parsers
        register_parsers(subparsers)

        # Test that all commands can be parsed
        test_commands = [
            "config --show",
            "scrape --config test.json",
            "github --repo owner/repo",
            "package output/test/",
            "upload test.zip",
            "analyze --directory .",
            "enhance output/test/",
            "estimate test.json",
        ]

        for cmd in test_commands:
            args = main_parser.parse_args(cmd.split())
            assert args.command is not None


class TestSpecificParsers:
    """Test specific parser implementations."""

    def test_scrape_parser_arguments(self):
        """Test ScrapeParser has correct arguments."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers(dest="command")

        scrape_parser = ScrapeParser()
        scrape_parser.create_parser(subparsers)

        # Test various argument combinations
        args = main_parser.parse_args(["scrape", "--config", "test.json"])
        assert args.command == "scrape"
        assert args.config == "test.json"

        args = main_parser.parse_args(["scrape", "--config", "test.json", "--max-pages", "100"])
        assert args.max_pages == 100

        args = main_parser.parse_args(["scrape", "--enhance-level", "2"])
        assert args.enhance_level == 2

    def test_github_parser_arguments(self):
        """Test GitHubParser has correct arguments."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers(dest="command")

        github_parser = GitHubParser()
        github_parser.create_parser(subparsers)

        args = main_parser.parse_args(["github", "--repo", "owner/repo"])
        assert args.command == "github"
        assert args.repo == "owner/repo"

        args = main_parser.parse_args(["github", "--repo", "owner/repo", "--non-interactive"])
        assert args.non_interactive is True

    def test_package_parser_arguments(self):
        """Test PackageParser has correct arguments."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers(dest="command")

        package_parser = PackageParser()
        package_parser.create_parser(subparsers)

        args = main_parser.parse_args(["package", "output/test/"])
        assert args.command == "package"
        assert args.skill_directory == "output/test/"

        args = main_parser.parse_args(["package", "output/test/", "--target", "gemini"])
        assert args.target == "gemini"

        args = main_parser.parse_args(["package", "output/test/", "--no-open"])
        assert args.no_open is True

    def test_analyze_parser_arguments(self):
        """Test AnalyzeParser has correct arguments."""
        main_parser = argparse.ArgumentParser()
        subparsers = main_parser.add_subparsers(dest="command")

        from skill_seekers.cli.parsers.analyze_parser import AnalyzeParser

        analyze_parser = AnalyzeParser()
        analyze_parser.create_parser(subparsers)

        args = main_parser.parse_args(["analyze", "--directory", "."])
        assert args.command == "analyze"
        assert args.directory == "."

        args = main_parser.parse_args(["analyze", "--directory", ".", "--quick"])
        assert args.quick is True

        args = main_parser.parse_args(["analyze", "--directory", ".", "--comprehensive"])
        assert args.comprehensive is True

        args = main_parser.parse_args(["analyze", "--directory", ".", "--skip-patterns"])
        assert args.skip_patterns is True


class TestBackwardCompatibility:
    """Test backward compatibility with old CLI."""

    def test_all_original_commands_still_work(self):
        """Test that all original commands are still registered."""
        names = get_parser_names()

        # Original commands from old main.py
        original_commands = [
            "config",
            "scrape",
            "github",
            "pdf",
            "unified",
            "enhance",
            "enhance-status",
            "package",
            "upload",
            "estimate",
            "extract-test-examples",
            "install-agent",
            "analyze",
            "install",
            "resume",
            "stream",
            "update",
            "multilang",
            "quality",
        ]

        for cmd in original_commands:
            assert cmd in names, f"Command '{cmd}' not found in parser registry!"

    def test_command_count_matches(self):
        """Test that we have exactly 21 commands (includes new create and workflows commands)."""
        assert len(PARSERS) == 21
        assert len(get_parser_names()) == 21


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
