import argparse
from orionis.test.contracts.parser import ITestArgumentParser
from orionis.test.entities.arguments import TestArguments

class TestArgumentParser(ITestArgumentParser):
    """
    A parser class for handling test command-line arguments.

    This class encapsulates the logic for creating and configuring the argument parser
    for the Orionis test runner, providing a clean interface for parsing test arguments.
    """

    def __init__(
        self
    ) -> None:
        """Initialize the argument parser with all required arguments."""
        self.parser = self.__create()

    def __create(
        self
    ) -> argparse.ArgumentParser:
        """
        Create and configure the argument parser with all test-related arguments.

        Returns
        -------
        argparse.ArgumentParser
            The configured argument parser instance.
        """
        parser = argparse.ArgumentParser(description="Run Orionis tests.")

        # Basic test configuration
        parser.add_argument(
            '--verbosity',
            type=int,
            default=2,
            help='Verbosity level (default: 2)'
        )

        parser.add_argument(
            '--mode',
            choices=['parallel', 'sequential'],
            default='parallel',
            help='Execution mode for tests (default: parallel)'
        )

        # Fail fast configuration
        parser.add_argument(
            '--fail_fast',
            dest='fail_fast',
            action='store_true',
            help='Stop on first failure'
        )
        parser.add_argument(
            '--no_fail_fast',
            dest='fail_fast',
            action='store_false',
            help='Do not stop on first failure (default)'
        )
        parser.set_defaults(fail_fast=False)

        # Print result configuration
        parser.add_argument(
            '--print_result',
            dest='print_result',
            action='store_true',
            help='Print test results to console (default)'
        )
        parser.add_argument(
            '--no_print_result',
            dest='print_result',
            action='store_false',
            help='Do not print test results to console'
        )
        parser.set_defaults(print_result=True)

        # Exception handling configuration
        parser.add_argument(
            '--throw_exception',
            dest='throw_exception',
            action='store_true',
            help='Throw exception on test failure'
        )
        parser.add_argument(
            '--no_throw_exception',
            dest='throw_exception',
            action='store_false',
            help='Do not throw exception on test failure (default)'
        )
        parser.set_defaults(throw_exception=False)

        # Persistent mode configuration
        parser.add_argument(
            '--persistent',
            dest='persistent',
            action='store_true',
            help='Run tests in persistent mode'
        )
        parser.add_argument(
            '--no_persistent',
            dest='persistent',
            action='store_false',
            help='Do not run tests in persistent mode (default)'
        )
        parser.set_defaults(persistent=False)

        parser.add_argument(
            '--persistent_driver',
            type=str,
            default=None,
            help='Persistent driver to use (default: None)'
        )

        # Web report configuration
        parser.add_argument(
            '--web_report',
            dest='web_report',
            action='store_true',
            help='Generate web report'
        )
        parser.add_argument(
            '--no_web_report',
            dest='web_report',
            action='store_false',
            help='Do not generate web report (default)'
        )
        parser.set_defaults(web_report=False)

        # Output buffer configuration
        parser.add_argument(
            '--print_output_buffer',
            dest='print_output_buffer',
            action='store_true',
            help='Print output buffer (for CI integrations)'
        )
        parser.add_argument(
            '--no_print_output_buffer',
            dest='print_output_buffer',
            action='store_false',
            help='Do not print output buffer (default)'
        )
        parser.set_defaults(print_output_buffer=False)

        return parser

    def parse(
        self,
        args=None
    ) -> TestArguments:
        """
        Parse command line arguments and return TestArguments object.

        Parameters
        ----------
        args : list, optional
            List of arguments to parse. If None, uses sys.argv.

        Returns
        -------
        TestArguments
            Parsed test arguments object.
        """
        return self.parser.parse_args(args)

    def help(
        self
    ) -> None:
        """Print help message for the test runner."""
        self.parser.print_help()

def test_parser_init() -> TestArgumentParser:
    """
    Factory function to create a TestArgumentParser instance.

    Returns
    -------
    TestArgumentParser
        A new instance of the test argument parser.
    """
    return TestArgumentParser()

def cli_test_args(args=None) -> TestArguments:
    """
    Convenience function to quickly parse test arguments.

    Parameters
    ----------
    args : list, optional
        List of arguments to parse. If None, uses sys.argv.

    Returns
    -------
    TestArguments
        Parsed test arguments object.
    """
    parser = test_parser_init()
    return parser.parse(args)