import os, glob, sys, importlib, glob, inspect

from ffx.show_controller import ShowController
from ffx.pattern_controller import PatternController
from ffx.media_controller import MediaController

from .helper import createEmptyDirectory
from ffx.database import databaseContext

class Scenario():
    """Scenarios
    
    Scenario1: MediaTags, Stream-Kombinationen, Dispositions und StreamTags per Kombinatoren

    Scenario2: <pattern> mit 3 Files x Scenario1

    Scenario3: <tmdb+pattern> mit 3 Files (wenn TMDB API Key verfügbar)

    Naming:

    1: test.mkv             no tmdb, no pattern
    2: test_s01e02.mkv
    
    Operationen:
    
    tmdb lookup: Set Showname as prefix, append episode name
    pattern lookup: Set/update tags/dispositions; Filter/Reorder Tracks

    MediaTag-Kombinationen (2)
    
    0: nichs
    1: Yolo=Holo

    Stream-Kombinationen (8)
    
    VA      D=1     T=1     =1
    VAS     D=1     T=1     =1
    VASS    D=4     T=4     =16
    VASSS   D=5     T=5     =25
    VAA     D=4     T=4     =16
    VAAS    D=4     T=4     =16
    VAASS   D=16    T=16    =256
    VAASSS  D=20    T=20    =400
                            =731

    Dispositions-Kombinationen (per TrackType)
    
    0 = keine
    1 = DEFAULT

    2 Streams (4):
    
    D1: 00
    D2: 01
    D3: 10
    D4: 11

    3 Streams (5):
    
    D5: 000
    D6: 001
    D7: 010
    D8: 100
    D9: 101

    Stream-Tag-Kombinationen (per TrackType)
    
    0 = keine
    1 = lang+title

    2 Streams:
    
    00
    01
    10
    11

    3 Streams:
    
    000
    001
    010
    100
    101
    
    
    
    """

    def __init__(self, context = None):
        self._context = context
        self._testDirectory = createEmptyDirectory()
        self._ffxModuleName = 'ffx'

        self._logger = context['logger']
        self._reportLogger = context['report_logger']

        self._testDbFilePath = os.path.join(self._testDirectory, 'test.db')
        self.createEmptyTestDatabase()

        # Convenience
        self._niceness = self._context['resource_limits']['niceness'] if 'resource_limits' in self._context.keys() and 'niceness' in self._context['resource_limits'].keys() else 99
        self._cpuPercent = self._context['resource_limits']['cpu_percent'] if 'resource_limits' in self._context.keys() and 'cpu_percent' in self._context['resource_limits'].keys() else 99


    def createEmptyTestDatabase(self):

        if not self._context['database'] is None:
            self._context['database']['engine'].dispose()

        if os.path.isfile(self._testDbFilePath):
            os.unlink(self._testDbFilePath)
        self._context['database'] = None

        self._logger.debug(f"Creating test db with path {self._testDbFilePath}")
        self._context['database'] = databaseContext(databasePath=self._testDbFilePath)

        self._sc = ShowController(context = self._context)
        self._pc = PatternController(context = self._context)
        self._mc = MediaController(context = self._context)
    

    def clearTestDirectory(self):
        testFiles = glob.glob(f"{self._testDirectory}/*")
        for f in testFiles:
            os.remove(f)

    def getFilePathsInTestDirectory(self):
        return [f for f in glob.glob(f"{self._testDirectory}/*")]

    def getFilenamesInTestDirectory(self):
        return [os.path.basename(f) for f in self.getFilePathsInTestDirectory()]


    @staticmethod    
    def list():
        basePath = os.path.dirname(__file__)
        return [os.path.basename(p)[9:-3]
                for p
                in glob.glob(f"{ basePath }/scenario_*.py", recursive = True)
                if p != __file__]

    @staticmethod
    def getClassReference(identifier):
        module_name = f"tests.legacy.scenario_{ identifier }"
        importlib.import_module(module_name)
        for name, obj in inspect.getmembers(sys.modules[module_name]):
            #HINT: Excluding Scenario as it seems to be included by import (?)
            if inspect.isclass(obj) and name != 'Scenario' and name.startswith('Scenario'):
                return obj
