__filename__ = "webapp_media.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.3.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Timeline"

import os
from utils import valid_url_prefix


def load_peertube_instances(base_dir: str, peertube_instances: []) -> None:
    """Loads peertube instances from file into the given list
    """
    peertube_list = None
    peertube_instances_filename = base_dir + '/accounts/peertube.txt'
    if os.path.isfile(peertube_instances_filename):
        with open(peertube_instances_filename, 'r') as fp_inst:
            peertube_str = fp_inst.read()
            if peertube_str:
                peertube_str = peertube_str.replace('\r', '')
                peertube_list = peertube_str.split('\n')
    if not peertube_list:
        return
    for url in peertube_list:
        if url in peertube_instances:
            continue
        peertube_instances.append(url)


def _add_embedded_video_from_sites(translate: {}, content: str,
                                   peertube_instances: [],
                                   width: int, height: int) -> str:
    """Adds embedded videos
    """
    if '>vimeo.com/' in content:
        url = content.split('>vimeo.com/')[1]
        if '<' in url:
            url = url.split('<')[0]
            content += \
                "<center>\n<span itemprop=\"video\">\n" + \
                "<iframe loading=\"lazy\" decoding=\"async\" " + \
                "src=\"https://player.vimeo.com/video/" + \
                url + "\" width=\"" + str(width) + \
                "\" height=\"" + str(height) + \
                "\" frameborder=\"0\" allow=\"" + \
                "fullscreen\" allowfullscreen></iframe>\n" + \
                "</span>\n</center>\n"
            return content

    video_site = 'https://www.youtube.com'
    if 'https://m.youtube.com' in content:
        content = content.replace('https://m.youtube.com', video_site)
    if '"' + video_site in content:
        url = content.split('"' + video_site)[1]
        if '"' in url:
            url = url.split('"')[0]
            if '/channel/' not in url and '/playlist' not in url:
                url = url.replace('/watch?v=', '/embed/')
                if '&' in url:
                    url = url.split('&')[0]
                if '?utm_' in url:
                    url = url.split('?utm_')[0]
                content += \
                    "<center>\n<span itemprop=\"video\">\n" + \
                    "<iframe loading=\"lazy\" " + \
                    "decoding=\"async\" src=\"" + \
                    video_site + url + "\" width=\"" + str(width) + \
                    "\" height=\"" + str(height) + \
                    "\" frameborder=\"0\" allow=\"fullscreen\" " + \
                    "allowfullscreen></iframe>\n" + \
                    "</span></center>\n"
                return content

    video_site = 'https://youtu.be/'
    if '"' + video_site in content:
        url = content.split('"' + video_site)[1]
        if '"' in url:
            url = url.split('"')[0]
            if '/channel/' not in url and '/playlist' not in url:
                url = 'embed/' + url
                if '&' in url:
                    url = url.split('&')[0]
                if '?utm_' in url:
                    url = url.split('?utm_')[0]
                video_site = 'https://www.youtube.com/'
                content += \
                    "<center>\n<span itemprop=\"video\">\n" + \
                    "<iframe loading=\"lazy\" " + \
                    "decoding=\"async\" src=\"" + \
                    video_site + url + "\" width=\"" + str(width) + \
                    "\" height=\"" + str(height) + \
                    "\" frameborder=\"0\" allow=\"fullscreen\" " + \
                    "allowfullscreen></iframe>\n" + \
                    "</span></center>\n"
                return content

    invidious_sites = (
        'https://invidious.snopyta.org',
        'https://yewtu.be',
        'https://tube.connect.cafe',
        'https://invidious.kavin.rocks',
        'https://invidiou.site',
        'https://invidious.tube',
        'https://invidious.xyz',
        'https://invidious.zapashcanon.fr',
        'http://c7hqkpkpemu6e7emz5b4vy' +
        'z7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion',
        'http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4' +
        'bzzsg2ii4fv2iid.onion'
    )
    for video_site in invidious_sites:
        if '"' + video_site in content:
            url = content.split('"' + video_site)[1]
            if '"' in url:
                url = url.split('"')[0].replace('/watch?v=', '/embed/')
                if '&' in url:
                    url = url.split('&')[0]
                if '?utm_' in url:
                    url = url.split('?utm_')[0]
                # explicitly turn off autoplay
                if '?' in url:
                    if '&autoplay=' not in url:
                        url += '&autoplay=0'
                    else:
                        url = url.replace('&autoplay=1', '&autoplay=0')
                else:
                    if '?autoplay=' not in url:
                        url += '?autoplay=0'
                    else:
                        url = url.replace('?autoplay=1', '?autoplay=0')
                content += \
                    "<center>\n<span itemprop=\"video\">\n" + \
                    "<iframe loading=\"lazy\" " + \
                    "decoding=\"async\" src=\"" + \
                    video_site + url + "\" width=\"" + \
                    str(width) + "\" height=\"" + str(height) + \
                    "\" frameborder=\"0\" allow=\"fullscreen\" " + \
                    "allowfullscreen></iframe>\n" + \
                    "</span>\n</center>\n"
                return content

    video_site = 'https://media.ccc.de'
    if '"' + video_site in content:
        url = content.split('"' + video_site)[1]
        if '"' in url:
            url = url.split('"')[0]
            video_site_settings = ''
            if '#' in url:
                video_site_settings = '#' + url.split('#', 1)[1]
                url = url.split('#')[0]
            if not url.endswith('/oembed'):
                url = url + '/oembed'
            url += video_site_settings
            content += \
                "<center>\n<span itemprop=\"video\">\n" + \
                "<iframe loading=\"lazy\" " + \
                "decoding=\"async\" src=\"" + \
                video_site + url + "\" width=\"" + \
                str(width) + "\" height=\"" + str(height) + \
                "\" frameborder=\"0\" allow=\"fullscreen\" " + \
                "allowfullscreen></iframe>\n" + \
                "</span>\n</center>\n"
            return content

    if '"https://' in content:
        if peertube_instances:
            # only create an embedded video for a limited set of
            # peertube sites.
            peertube_sites = peertube_instances
        else:
            # A default minimal set of peertube instances
            # Also see https://peertube_isolation.frama.io/list/ for
            # adversarial instances. Nothing in that list should be
            # in the defaults below.
            peertube_sites = (
                'share.tube',
                'visionon.tv',
                'anarchy.tube',
                'peertube.fr',
                'video.nerdcave.site',
                'kolektiva.media',
                'peertube.social',
                'videos.lescommuns.org'
            )
        for site in peertube_sites:
            site = site.strip()
            if not site:
                continue
            if len(site) < 5:
                continue
            if '.' not in site:
                continue
            site_str = site
            if site.startswith('http://'):
                site = site.replace('http://', '')
            elif site.startswith('https://'):
                site = site.replace('https://', '')
            if site.endswith('.onion') or site.endswith('.i2p'):
                site_str = 'http://' + site
            else:
                site_str = 'https://' + site
            site_str = '"' + site_str
            if site_str not in content:
                continue
            url = content.split(site_str)[1]
            if '"' not in url:
                continue
            url = url.split('"')[0]
            if '/c/' in url:
                # don't try to embed peertube channel page
                continue
            if '?sort=' in url:
                # don't try to embed a sorted list
                continue
            if '/w/' in url:
                if '/videos/' not in url:
                    url = url.replace('/w/', '/videos/embed/')
                else:
                    url = url.replace('/w/', '/embed/')
            url = url.replace('/watch/', '/embed/')

            content += \
                "<center>\n<span itemprop=\"video\">\n" + \
                "<iframe loading=\"lazy\" decoding=\"async\" " + \
                "sandbox=\"allow-same-origin " + \
                "allow-scripts\" src=\"https://" + \
                site + url + "\" width=\"" + str(width) + \
                "\" height=\"" + str(height) + \
                "\" frameborder=\"0\" allow=\"" + \
                "fullscreen\" allowfullscreen></iframe>\n" + \
                "</span>\n</center>\n"
            return content
    return content


def _add_embedded_audio(translate: {}, content: str) -> str:
    """Adds embedded audio for mp3/ogg/opus
    """
    if not ('.mp3' in content or
            '.ogg' in content or
            '.opus' in content or
            '.flac' in content):
        return content

    if '<audio ' in content:
        return content

    extension = '.mp3'
    if '.ogg' in content:
        extension = '.ogg'
    elif '.opus' in content:
        extension = '.opus'
    elif '.flac' in content:
        extension = '.flac'

    words = content.strip('\n').split(' ')
    for wrd in words:
        if extension not in wrd:
            continue
        wrd = wrd.replace('href="', '').replace('">', '')
        if wrd.endswith('.'):
            wrd = wrd[:-1]
        if wrd.endswith('"'):
            wrd = wrd[:-1]
        if wrd.endswith(';'):
            wrd = wrd[:-1]
        if wrd.endswith(':'):
            wrd = wrd[:-1]
        if not wrd.endswith(extension):
            continue

        if not valid_url_prefix(wrd):
            continue
        content += \
            '<center>\n<span itemprop="audio">' + \
            '<audio controls>\n' + \
            '<source src="' + wrd + '" type="audio/' + \
            extension.replace('.', '') + '">' + \
            translate['Your browser does not support the audio element.'] + \
            '</audio>\n</span>\n</center>\n'
    return content


def _add_embedded_video(translate: {}, content: str) -> str:
    """Adds embedded video for mp4/webm/ogv
    """
    if not ('.mp4' in content or '.webm' in content or '.ogv' in content):
        return content

    if '<video ' in content:
        return content

    extension = '.mp4'
    if '.webm' in content:
        extension = '.webm'
    elif '.ogv' in content:
        extension = '.ogv'

    words = content.strip('\n').split(' ')
    for wrd in words:
        if extension not in wrd:
            continue
        wrd = wrd.replace('href="', '').replace('">', '')
        if wrd.endswith('.'):
            wrd = wrd[:-1]
        if wrd.endswith('"'):
            wrd = wrd[:-1]
        if wrd.endswith(';'):
            wrd = wrd[:-1]
        if wrd.endswith(':'):
            wrd = wrd[:-1]
        if not wrd.endswith(extension):
            continue
        if not valid_url_prefix(wrd):
            continue
        content += \
            '<center><span itemprop="video">\n' + \
            '<figure id="videoContainer" ' + \
            'data-fullscreen="false">\n' + \
            '    <video id="video" controls ' + \
            'preload="metadata">\n' + \
            '<source src="' + wrd + '" type="video/' + \
            extension.replace('.', '') + '">\n' + \
            translate['Your browser does not support the video element.'] + \
            '</video>\n</figure>\n</span>\n</center>\n'
    return content


def add_embedded_elements(translate: {}, content: str,
                          peertube_instances: []) -> str:
    """Adds embedded elements for various media types
    """
    content = _add_embedded_video_from_sites(translate, content,
                                             peertube_instances, 400, 300)
    content = _add_embedded_audio(translate, content)
    return _add_embedded_video(translate, content)