from pathlib import Path
from typing import Any, List, Tuple

from .._virtual_scenario import VirtualScenario
from ._scenario_orderer import ScenarioOrderer

__all__ = ("StableScenarioOrderer",)


class StableScenarioOrderer(ScenarioOrderer):
    """
    A scenario orderer that maintains a stable order based on the file paths of scenarios.

    The `StableScenarioOrderer` ensures that scenarios are ordered based on their file paths
    in a consistent and predictable manner.
    """

    def _cmp(self, scn: VirtualScenario) -> Tuple[Any, ...]:
        """
        Generate a comparison key based on the scenario's file path.

        The key is generated by using the number of parts in the path and the length of
        each part, ensuring stable ordering.

        :param scn: The `VirtualScenario` instance whose path is being used for comparison.
        :return: A tuple used as a sorting key based on the scenario's file path.
        """
        path = Path(scn.path)
        return (len(path.parts),) + tuple((len(x), x) for x in path.parts)

    async def sort(self, scenarios: List[VirtualScenario]) -> List[VirtualScenario]:
        """
        Sort the scenarios in a stable order based on their file paths.

        This method ensures a consistent order of scenarios by using a comparison
        key derived from the structure and content of their file paths.

        :param scenarios: The list of `VirtualScenario` instances to be sorted.
        :return: A new list of scenarios sorted in a stable order.
        """
        return list(sorted(scenarios, key=self._cmp))
