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

from ffx.track_type import TrackType

from ffx.track_descriptor import TrackDescriptor
from ffx.media_descriptor import MediaDescriptor

from .basename_combinator import BasenameCombinator

from .indicator_combinator import IndicatorCombinator
from .label_combinator import LabelCombinator


class BasenameCombinator0(BasenameCombinator):
    """base[_indicator]"""

    VARIANT = 'B0'

    # def __init__(self, SubCombinators: dict = {}, context = None):
    def __init__(self, context = None):
        self._context = context
        self._logger = context['logger']
        self._reportLogger = context['report_logger']

    def getVariant(self):
        return BasenameCombinator0.VARIANT

    def getPayload(self, indicator = '', label = ''):

        basename = BasenameCombinator.BASENAME
        expectedBasename = label if label else BasenameCombinator.BASENAME

        if indicator:
            basename += f"_{indicator}"
            expectedBasename += f"_{indicator}"

        return {'basename': basename,
                'label': label,
                'expectedBasename': expectedBasename}


    def assertFunc(self, indicator = '', label = ''):

        def f(testObj: dict = {}):

            if not 'filenames' in testObj.keys():
                raise KeyError("testObj does not contain key 'filenames'")

            fNames = testObj['filenames']

            assert len(fNames) == 1, "More than one result file was created"

            resultFilename = fNames[0]

            fTokens = resultFilename.split('.')

            resultBasename = '.'.join(fTokens[:-1])
            resultExtension = fTokens[-1]

            if not indicator and not label:
                
                assert resultBasename == BasenameCombinator.BASENAME, f"Result basename is not {BasenameCombinator.BASENAME}"
            if not indicator and     label:
                assert resultBasename == label, f"Result basename is not {label}"
            if     indicator and not label:
                assert resultBasename == f"{BasenameCombinator.BASENAME}_{indicator}", f"Result basename is not {BasenameCombinator.BASENAME}_{indicator}"
            if     indicator and     label:
                assert resultBasename == f"{label}_{indicator}", f"Result basename is not {label}_{indicator}"

        return f


    def shouldFail(self):
        return False

    def getYield(self):

        ic = IndicatorCombinator(self._context)

        for L in LabelCombinator.getAllClassReferences():
            for i in ic.getYield():

                l = L(self._context)

                indicator = i['indicator']
                indicatorVariant = i['variant']

                yieldObj = {}

                yieldObj['identifier'] = self.getIdentifier()

                yieldObj['variants'] = [self.getVariant(),
                                        l.getVariant(),
                                        indicatorVariant]

                yieldObj['payload'] = self.getPayload(indicator = indicator,
                                                        label = l.getPayload())

                yieldObj['assertSelectors'] = ['B', 'L', 'I']

                yieldObj['assertFuncs'] = [self.assertFunc(indicator, l.getPayload()), l.assertFunc, ic.assertFunc]

                yieldObj['shouldFail'] = (self.shouldFail()
                                            | l.shouldFail()
                                            | ic.shouldFail())

                yield yieldObj
