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 .media_combinator import MediaCombinator

from .disposition_combinator_2 import DispositionCombinator2
from .disposition_combinator_3 import DispositionCombinator3
from .track_tag_combinator_2 import TrackTagCombinator2
from .track_tag_combinator_3 import TrackTagCombinator3
from .permutation_combinator_2 import PermutationCombinator2
from .permutation_combinator_3 import PermutationCombinator3
from .media_tag_combinator import MediaTagCombinator

class MediaCombinator7(MediaCombinator):

    VARIANT = 'VAASSS'

    def __init__(self, context = None,
                    createPresets: bool = False):
        super().__init__(context)

        self.__createPresets = createPresets


    def getVariant(self):
        return MediaCombinator7.VARIANT


    def getPayload(self,
                    audioPermutation,
                    subtitlePermutation,
                    audioDispositionTuple = (set(), set()),
                    audioTagTuple = ({}, {}),
                    subtitleDispositionTuple = (set(), set(), set()),
                    subtitleTagTuple = ({}, {}, {})):

        kwargs = {}
        kwargs[TrackDescriptor.CONTEXT_KEY] = self._context
        kwargs[TrackDescriptor.INDEX_KEY] = 0
        kwargs[TrackDescriptor.SOURCE_INDEX_KEY] = 0
        kwargs[TrackDescriptor.TRACK_TYPE_KEY] = TrackType.VIDEO
        kwargs[TrackDescriptor.SUB_INDEX_KEY] = 0
        trackDescriptor0 = TrackDescriptor(**kwargs)

        kwargs = {}
        kwargs[TrackDescriptor.CONTEXT_KEY] = self._context
        kwargs[TrackDescriptor.INDEX_KEY] = 1
        kwargs[TrackDescriptor.SOURCE_INDEX_KEY] = 1
        kwargs[TrackDescriptor.TRACK_TYPE_KEY] = TrackType.AUDIO
        kwargs[TrackDescriptor.SUB_INDEX_KEY] = 0
        kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = audioDispositionTuple[0]
        kwargs[TrackDescriptor.TAGS_KEY] = audioTagTuple[0]
        trackDescriptor1 = TrackDescriptor(**kwargs)

        kwargs = {}
        kwargs[TrackDescriptor.CONTEXT_KEY] = self._context
        kwargs[TrackDescriptor.INDEX_KEY] = 2
        kwargs[TrackDescriptor.SOURCE_INDEX_KEY] = 2
        kwargs[TrackDescriptor.TRACK_TYPE_KEY] = TrackType.AUDIO
        kwargs[TrackDescriptor.SUB_INDEX_KEY] = 1
        kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = audioDispositionTuple[1]
        kwargs[TrackDescriptor.TAGS_KEY] = audioTagTuple[1]
        trackDescriptor2 = TrackDescriptor(**kwargs)

        kwargs = {}
        kwargs[TrackDescriptor.CONTEXT_KEY] = self._context
        kwargs[TrackDescriptor.INDEX_KEY] = 3
        kwargs[TrackDescriptor.SOURCE_INDEX_KEY] = 3
        kwargs[TrackDescriptor.TRACK_TYPE_KEY] = TrackType.SUBTITLE
        kwargs[TrackDescriptor.SUB_INDEX_KEY] = 0
        kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = subtitleDispositionTuple[0]
        kwargs[TrackDescriptor.TAGS_KEY] = subtitleTagTuple[0]
        trackDescriptor3 = TrackDescriptor(**kwargs)

        kwargs = {}
        kwargs[TrackDescriptor.CONTEXT_KEY] = self._context
        kwargs[TrackDescriptor.INDEX_KEY] = 4
        kwargs[TrackDescriptor.SOURCE_INDEX_KEY] = 4
        kwargs[TrackDescriptor.TRACK_TYPE_KEY] = TrackType.SUBTITLE
        kwargs[TrackDescriptor.SUB_INDEX_KEY] = 1
        kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = subtitleDispositionTuple[1]
        kwargs[TrackDescriptor.TAGS_KEY] = subtitleTagTuple[1]
        trackDescriptor4 = TrackDescriptor(**kwargs)

        kwargs = {}
        kwargs[TrackDescriptor.CONTEXT_KEY] = self._context
        kwargs[TrackDescriptor.INDEX_KEY] = 5
        kwargs[TrackDescriptor.SOURCE_INDEX_KEY] = 5
        kwargs[TrackDescriptor.TRACK_TYPE_KEY] = TrackType.SUBTITLE
        kwargs[TrackDescriptor.SUB_INDEX_KEY] = 2
        kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = subtitleDispositionTuple[2]
        kwargs[TrackDescriptor.TAGS_KEY] = subtitleTagTuple[2]
        trackDescriptor5 = TrackDescriptor(**kwargs)

        kwargs = {}
        kwargs[MediaDescriptor.CONTEXT_KEY] = self._context
        kwargs[MediaDescriptor.TRACK_DESCRIPTOR_LIST_KEY] = [trackDescriptor0,
                trackDescriptor1,
                trackDescriptor2,
                trackDescriptor3,
                trackDescriptor4,
                trackDescriptor5]

        mediaDescriptor = MediaDescriptor(**kwargs)
        # mediaDescriptor.reindexSubIndices()

        return mediaDescriptor


    def assertFunc(self, testObj = {}):
        pass

    def shouldFail(self):
        return False

    def getYield(self):


        pc2 = PermutationCombinator2(self._context)
        pc3 = PermutationCombinator3(self._context)

        for MTC in MediaTagCombinator.getAllClassReferences():
            for DC2_A in DispositionCombinator2.getAllClassReferences():
                for TC2_A in TrackTagCombinator2.getAllClassReferences():
                    for DC3_S in DispositionCombinator3.getAllClassReferences():
                        for TC3_S in TrackTagCombinator3.getAllClassReferences():
                            for p2y in pc2.getYield():
                                for p3y in pc3.getYield():

                                    dc2a = DC2_A(self._context)
                                    tc2a = TC2_A(self._context)
                                    dc3s = DC3_S(self._context)
                                    tc3s = TC3_S(self._context)

                                    mtc = MTC(self._context)

                                    yObj = {}

                                    yObj['identifier'] = self.getIdentifier()
                                    yObj['variants'] = [self.getVariant(),
                                                            f"A:{p2y['variant']}",
                                                            f"S:{p3y['variant']}",
                                                            f"A:{dc2a.getVariant()}",
                                                            f"A:{tc2a.getVariant()}",
                                                            f"S:{dc3s.getVariant()}",
                                                            f"S:{tc3s.getVariant()}",
                                                            mtc.getVariant()]

                                    yObj['payload'] = self.getPayload(p2y['permutation'],
                                                                      p3y['permutation'],
                                                                      dc2a.getPayload(),
                                                                        tc2a.getPayload(),
                                                                        dc3s.getPayload(),
                                                                        tc3s.getPayload())

                                    yObj['assertSelectors'] = ['M', 'AP', 'SP', 'AD', 'AT', 'SD', 'ST', 'MT']

                                    yObj['assertFuncs'] = [self.assertFunc,
                                                                p2y['assertFunc'],
                                                                p3y['assertFunc'],
                                                                dc2a.createAssertFunc(),
                                                                tc2a.createAssertFunc(),
                                                                dc3s.createAssertFunc(),
                                                                tc3s.createAssertFunc(),
                                                                mtc.createAssertFunc()]

                                    yObj['shouldFail'] = (self.shouldFail()
                                                                | p2y['shouldFail']
                                                                | p3y['shouldFail']
                                                                | dc2a.shouldFail()
                                                                | tc2a.shouldFail()
                                                                | dc3s.shouldFail()
                                                                | tc3s.shouldFail()
                                                                | mtc.shouldFail())
                                    yieldObj = {'target': yObj}

                                    if self.__createPresets:

                                        dc2a_p = DC2_A(self._context, createPresets = True)
                                        tc2a_p = TC2_A(self._context, createPresets = True)
                                        dc3s_p = DC3_S(self._context, createPresets = True)
                                        tc3s_p = TC3_S(self._context, createPresets = True)

                                        mtc_p = MTC(self._context, createPresets = True)

                                        yObj_p = {}

                                        yObj_p['identifier'] = self.getIdentifier()
                                        yObj_p['variants'] = [self.getVariant(),
                                                                f"A:{p2y['variant']}",
                                                                f"S:{p3y['variant']}",
                                                                f"A:{dc2a_p.getVariant()}",
                                                                f"A:{tc2a_p.getVariant()}",
                                                                f"S:{dc3s_p.getVariant()}",
                                                                f"S:{tc3s_p.getVariant()}",
                                                                mtc_p.getVariant()]

                                        yObj_p['payload'] = self.getPayload(p2y['permutation'],
                                                                            p3y['permutation'],
                                                                            dc2a_p.getPayload(),
                                                                            tc2a_p.getPayload(),
                                                                            dc3s_p.getPayload(),
                                                                            tc3s_p.getPayload())

                                        yObj_p['assertSelectors'] = ['M', 'AP', 'SP', 'AD', 'AT', 'SD', 'ST', 'MT']

                                        yObj_p['assertFuncs'] = [self.assertFunc,
                                                                    p2y['assertFunc'],
                                                                    p3y['assertFunc'],
                                                                    dc2a_p.createAssertFunc(),
                                                                    tc2a_p.createAssertFunc(),
                                                                    dc3s_p.createAssertFunc(),
                                                                    tc3s_p.createAssertFunc(),
                                                                    mtc_p.createAssertFunc()]

                                        yObj_p['shouldFail'] = (self.shouldFail()
                                                                    | p2y['shouldFail']
                                                                    | p3y['shouldFail']
                                                                    | dc2a_p.shouldFail()
                                                                    | tc2a_p.shouldFail()
                                                                    | dc3s_p.shouldFail()
                                                                    | tc3s_p.shouldFail()
                                                                    | mtc_p.shouldFail())
                                        yieldObj['preset'] = yObj_p

                                    yield yieldObj
