from enum import Enum
from .track_type import TrackType

class AudioLayout(Enum):

    LAYOUT_STEREO   = {"label": "stereo", "index": 1}
    LAYOUT_5_1      = {"label": "5.1(side)", "index": 2}
    LAYOUT_6_1      = {"label": "6.1", "index": 3}
    LAYOUT_7_1      = {"label": "7.1", "index": 4} #TODO: Does this exist?

    LAYOUT_6CH      = {"label": "6ch", "index": 5}
    LAYOUT_5_0      = {"label": "5.0(side)", "index": 6}

    LAYOUT_UNDEFINED  = {"label": "undefined", "index": 0}


    def label(self):
        """Returns the audio layout as string"""
        return str(self.value['label'])

    def index(self):
        """Returns the audio layout as integer"""
        return int(self.value['index'])

    @staticmethod
    def fromLabel(label : str):
        try:
            
            return [a for a in AudioLayout if a.value['label'] == str(label)][0]
        except:
            return AudioLayout.LAYOUT_UNDEFINED

    # @staticmethod
    # def fromIndex(index : int):
    #     try:
    #         target_index = int(index)
    #     except (TypeError, ValueError):
    #         return AudioLayout.LAYOUT_UNDEFINED
    #     return next((a for a in AudioLayout if a.value['index'] == target_index),
    #                 AudioLayout.LAYOUT_UNDEFINED)

    @staticmethod
    def fromIndex(index : int):
        try:
            return [a for a in AudioLayout if a.value['index'] == int(index)][0]
        except:
            return AudioLayout.LAYOUT_UNDEFINED

    @staticmethod
    def identify(streamObj):

        FFPROBE_LAYOUT_KEY = 'channel_layout'
        FFPROBE_CHANNELS_KEY = 'channels'
        FFPROBE_CODEC_TYPE_KEY = 'codec_type'

        if (type(streamObj) is not dict
                or FFPROBE_CODEC_TYPE_KEY not in streamObj.keys()
                or streamObj[FFPROBE_CODEC_TYPE_KEY] != TrackType.AUDIO.label()):
            raise Exception('Not an ffprobe audio stream object')

        if FFPROBE_LAYOUT_KEY in streamObj.keys():
            matchingLayouts = [l for l in AudioLayout if l.label() == streamObj[FFPROBE_LAYOUT_KEY]]
            if matchingLayouts:
                return matchingLayouts[0]

        if (FFPROBE_CHANNELS_KEY in streamObj.keys()
                and int(streamObj[FFPROBE_CHANNELS_KEY]) == 6):

            return AudioLayout.LAYOUT_6CH
  
        return AudioLayout.LAYOUT_UNDEFINED
