import unittest
from abc import ABC, abstractmethod
from typing import Any, Dict, List

class IUnitTest(ABC):

    @abstractmethod
    def setModule(
        self,
        module: str
    ) -> None:
        """
        Add a specific module name to the list of modules for test discovery.

        This method appends the provided module name to the internal list of specific modules
        (`__specific_modules`). These modules will be considered during test discovery and loading.

        Parameters
        ----------
        module : str
            The name of the module to add for test discovery.

        Returns
        -------
        None
            This method does not return any value. It updates the internal module list.

        Notes
        -----
        - The module name should be a string representing the fully qualified module path.
        - This method is useful for targeting specific modules for test execution.
        """
        pass

    @abstractmethod
    def run(self) -> Dict[str, Any]:
        """
        Execute the test suite and return a summary of the results.

        Returns
        -------
        dict
            Dictionary summarizing the test results, including statistics and execution time.

        Raises
        ------
        OrionisTestFailureException
            If the test suite execution fails and throw_exception is True.
        """
        pass

    @abstractmethod
    def getDiscoveredTestCases(
        self
    ) -> List[unittest.TestCase]:
        """
        Return a list of all discovered test case classes in the test suite.

        This method provides access to all unique test case classes that have been discovered
        during test suite initialization and loading. It does not execute any tests, but simply
        reports the discovered test case classes.

        Returns
        -------
        List[unittest.TestCase]
            A list of unique `unittest.TestCase` classes that have been discovered in the suite.

        Notes
        -----
        - The returned list contains the test case classes, not instances or names.
        - The classes are derived from the `__class__` attribute of each discovered test case.
        - This method is useful for introspection or reporting purposes.
        """
        pass

    @abstractmethod
    def getDiscoveredModules(
        self
    ) -> List:
        """
        Return a list of all discovered test module names in the test suite.

        This method provides access to all unique test modules that have been discovered
        during test suite initialization and loading. It does not execute any tests, but simply
        reports the discovered module names.

        Parameters
        ----------
        None

        Returns
        -------
        List[str]
            A list of unique module names (as strings) that have been discovered in the suite.

        Notes
        -----
        - The returned list contains the module names, not module objects.
        - The module names are derived from the `__module__` attribute of each discovered test case.
        - This method is useful for introspection or reporting purposes.
        """
        pass

    @abstractmethod
    def getTestIds(
        self
    ) -> List[str]:
        """
        Return a list of all unique test IDs discovered in the test suite.

        This method provides access to the unique identifiers (IDs) of all test cases
        that have been discovered and loaded into the suite. The IDs are collected from
        each `unittest.TestCase` instance during test discovery and are returned as a list
        of strings. This is useful for introspection, reporting, or filtering purposes.

        Parameters
        ----------
        None

        Returns
        -------
        List[str]
            A list of strings, where each string is the unique ID of a discovered test case.
            The IDs are generated by the `id()` method of each `unittest.TestCase` instance.

        Notes
        -----
        - The returned list contains only unique test IDs.
        - This method does not execute any tests; it only reports the discovered IDs.
        - The IDs typically include the module, class, and method name for each test case.
        """
        pass

    @abstractmethod
    def getTestCount(
        self
    ) -> int:
        """
        Return the total number of individual test cases discovered in the test suite.

        This method calculates and returns the total number of test cases that have been
        discovered and loaded into the suite, including all modules and filtered tests.
        It uses the internal metadata collected during test discovery to provide an accurate count.

        Returns
        -------
        int
            The total number of individual test cases discovered and loaded in the suite.

        Notes
        -----
        - The count reflects all tests after applying any name pattern or folder filtering.
        - This method does not execute any tests; it only reports the discovered count.
        """
        pass

    @abstractmethod
    def getResult(
        self
    ) -> dict:
        """
        Get the results of the executed test suite.

        Returns
        -------
        dict
            Result of the executed test suite.
        """
        pass