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
from .title_combinator import TitleCombinator
from .release_combinator import ReleaseCombinator
from .show_combinator import ShowCombinator


class BasenameCombinator2(BasenameCombinator):
    """show[_indicator]_group"""

    VARIANT = 'B2'

    # 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 BasenameCombinator2.VARIANT

#
#    SHOW_LIST = [
#        'Boruto: Naruto Next Generations (2017)',
#        'The Rising of the Shield Hero (2019)',
#        'Scrubs - Die Anfänger (2001)'
#    ]
#
#    RELEASE_LIST = [
#        ".GerEngSub.AAC.1080pINDICATOR.WebDL.x264-Tanuki",
#        ".German.AC3.DL.1080pINDICATOR.BluRay.x264-AST4u",
#        "-720pINDICATOR"
#    ]


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

        if label:
            basename = label
            expectedBasename = label
            if indicator:
                basename += f"_{indicator}"
                expectedBasename += f"_{indicator}"
        else:
            basename = show+release
            expectedBasename = basename

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


    def createAssertFunc(self,
                    indicator = '',
                    label = '',
                    show = '',
                    release = ''):

        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 == show+release, f"Result basename is not {show+release}"
            elif not indicator and     label:
                assert resultBasename == label, f"Result basename is not {label}"
            elif     indicator and not label:
                assert resultBasename == show+release, f"Result basename is not {show+release}"
            elif     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)
        sc = ShowCombinator(self._context)

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

                indicator = iy['indicator']
                indicatorVariant = iy['variant']

                rc = ReleaseCombinator(self._context, indicator=indicator)

                for sy in sc.getYield():
                    for ry in rc.getYield():

                        l = L(self._context)

                        show = sy['show']
                        showVariant = sy['variant']

                        release = ry['release']
                        releaseVariant = ry['variant']

                        yieldObj = {}

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

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

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

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

                        yieldObj['assertFuncs'] = [self.createAssertFunc(indicator,
                                                                    l.getPayload(),
                                                                    show = show,
                                                                    release = release),
                                                    l.assertFunc,
                                                    ic.assertFunc,
                                                    sc.assertFunc,
                                                    rc.assertFunc]

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

                        yield yieldObj
