# This file is part of yle-dl.
#
# Copyright 2010-2022 Antti Ajanki and others
#
# Yle-dl is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Yle-dl is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with yle-dl. If not, see <https://www.gnu.org/licenses/>.

import logging
from .backends import DASHHLSBackend
from .streamflavor import StreamFlavor, failed_flavor

logger = logging.getLogger('yledl')


class FullHDFlavorProber:
    def probe_flavors(self, manifest_url, is_live, ffprobe):
        try:
            programs = ffprobe.show_programs_for_url(manifest_url)
        except ValueError as ex:
            return [failed_flavor(f'Failed to probe stream: {str(ex)}')]

        return self.programs_to_stream_flavors(programs, manifest_url, is_live)

    def programs_to_stream_flavors(self, programs, manifest_url, is_live):
        res = []
        for program in programs.get('programs', []):
            streams = program.get('streams', [])
            any_stream_is_video = any(x['codec_type'] == 'video'
                                      for x in streams if 'codec_type' in x)
            widths = [x['width'] for x in streams if 'width' in x]
            heights = [x['height'] for x in streams if 'height' in x]
            bitrate = program.get('tags', {}).get('variant_bitrate')
            if bitrate:
                bitrate = int(bitrate) / 1000

            pid = program.get('program_id')
            res.append(StreamFlavor(
                media_type='video' if any_stream_is_video else 'audio',
                height=heights[0] if heights else None,
                width=widths[0] if widths else None,
                bitrate=bitrate,
                streams=[
                    DASHHLSBackend(manifest_url, long_probe=True,
                                   program_id=pid, is_live=is_live,
                                   experimental_subtitles=True)
                ]
            ))

        res = self._drop_duplicates(res)
        return sorted(res, key=lambda x: (x.height or 0, x.bitrate or 0))

    def _drop_duplicates(self, stream_flavors):
        def flavor_key(s):
            return (s.width, s.height, s.bitrate, next((x.url for x in s.streams), None))

        unique = {flavor_key(s): s for s in stream_flavors}
        return unique.values()
