#!/usr/bin/python3
import sys
import os
import o11
import base64
import json
import datetime
import pytz
import requests
import pickle
from bs4 import BeautifulSoup

WVD_PATH = './WVD.wvd'

user = o11.parse_params(sys.argv, 'user')
password = o11.parse_params(sys.argv, 'password')
device_param = o11.parse_params(sys.argv, 'device')
pin = o11.parse_params(sys.argv, 'pin')

id = o11.parse_params(sys.argv, 'id')
action = o11.parse_params(sys.argv, 'action')

bind = o11.parse_params(sys.argv, 'bind')
proxy = o11.parse_params(sys.argv, 'proxy')
doh = o11.parse_params(sys.argv, 'doh')
worker = o11.parse_params(sys.argv, 'worker')

cdm = o11.parse_params(sys.argv, 'cdm')
drm = o11.parse_params(sys.argv, 'drm')
kid = o11.parse_params(sys.argv, 'kid')
pssh = o11.parse_params(sys.argv, 'pssh')
challenge = o11.parse_params(sys.argv, 'challenge')

heartbeaturl = o11.parse_params(sys.argv, 'heartbeaturl')
heartbeatparams = o11.parse_params(sys.argv, 'heartbeatparams')

o11Session = o11.session(bind=bind, proxy=proxy, worker=worker)
req = o11Session.get_session()
if doh != "":
    o11.dns(doh)

if challenge == "cert":
    challenge = "CAQ="

authFile = '/Televio_' + user + '.tokens'
sessionFile = '/Televio_' + user + '.session'
proxies = {"http": proxy, "https": proxy} if proxy else {}

user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'

def get_channels(session_cookies):
    cookies = {'streamQuality': '60'}
    cookies.update(session_cookies)
    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'referer': 'https://televio.hr/epg',
        'user-agent': user_agent,
    }
    response = req.get('https://televio.hr/home', headers=headers, cookies=cookies)
    soup = BeautifulSoup(response.content, features="lxml")
    data = json.loads(soup.find('script', {'id': 'player.playlist'}).text)
    r = []
    for k, v in data.items():
        r.append(v)
    return r

def do_login_request(username, pwd):
    session = requests.Session()
    if proxy:
        session.proxies.update(proxies)
    
    headers = {
        'authority': 'televio.hr',
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'user-agent': user_agent,
    }
    response = session.get('https://televio.hr/welcome/login', headers=headers)
    cookies = response.cookies.get_dict()

    headers = {
        'Host': 'televio.hr',
        'User-Agent': user_agent,
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Origin': 'https://televio.hr',
        'Referer': 'https://televio.hr/welcome/login',
    }
    data = {
        'username': username,
        'password': pwd,
        'login': 'Prijavi se',
        '_do': 'userLoginControl-signInForm-submit',
    }
    response = session.post('https://televio.hr/welcome/login', headers=headers, data=data, allow_redirects=False, cookies=cookies)
    loc = response.headers['Location']
    cookies = response.cookies.get_dict()

    headers = {
        'Host': 'televio.hr',
        'User-Agent': user_agent,
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Referer': 'https://televio.hr/welcome/login',
    }
    response = session.get(loc, headers=headers, cookies=cookies, allow_redirects=False)
    loc = response.headers['Location'].split('?')[0]
    response = session.get(loc, headers=headers, cookies=cookies, allow_redirects=False)
    profile_id = response.headers['x-ott-userid']

    response = session.get(f'https://televio.hr/profile?profileId={profile_id}&do=switchProfile', headers=headers, allow_redirects=False, cookies=cookies)
    
    headers = {
        'authority': 'televio.hr',
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'referer': 'https://televio.hr/profile?backlink=foq0j',
        'user-agent': user_agent,
    }
    response = session.get('https://televio.hr/home', cookies=cookies, headers=headers)
    
    return dict(session.cookies)

def login():
    print("logging in...", file=sys.stderr)
    session_cookies = do_login_request(user, password)
    auth_data = {'username': user, 'password': password, 'cookies': session_cookies}
    json.dump(auth_data, open(os.path.abspath(os.path.dirname(__file__)) + authFile, 'w'))
    print("logged in successfully", file=sys.stderr)

def do_action():
    if action == "login":
        login()
        sys.exit()

    try:
        auth = json.load(open(os.path.abspath(os.path.dirname(__file__)) + authFile))
        session_cookies = do_login_request(auth['username'], auth['password'])
    except:
        return "error"

    if action == "channels":
        output = {'Channels': []}
        channels = get_channels(session_cookies)
        for chan in channels:
            channel = {
                'Name': chan['name'],
                'Mode': "live",
                'SessionManifest': True,
                'ManifestScript': 'id=' + str(chan['name']),
                'CdmType': "none",
                'UseCdm': False,
                'Video': 'best',
                'OnDemand': True,
                'SpeedUp': True
            }
            output['Channels'].append(channel)
        print(json.dumps(output, indent=2))

    elif action == "events":
        output = {'Events': []}
        channels = get_channels(session_cookies)
        for chan in channels:
            event = {
                'Name': chan['name'],
                'Mode': "live",
                'SessionManifest': True,
                'ManifestScript': 'id=' + str(chan['name']),
                'CdmType': "none",
                'UseCdm': False,
                'Video': 'best',
                'Autostart': True,
                'Start': int(datetime.datetime.now(pytz.UTC).timestamp()),
                'End': int((datetime.datetime.now(pytz.UTC) + datetime.timedelta(hours=4)).timestamp())
            }
            output['Events'].append(event)
        print(json.dumps(output, indent=2))

    elif action == "heartbeat":
        sys.exit()

    elif action == "manifest":
        channel_name = id
        try:
            channels = get_channels(session_cookies)
            chan = None
            for c in channels:
                if c['name'] == channel_name:
                    chan = c
                    break
            
            if not chan:
                print("Channel not found", file=sys.stderr)
                return "error"
            
            url = chan['url']
            
            output = {
                "Cdn": [],
                "ManifestUrl": url,
                "Headers": {
                    "Manifest": {'User-Agent': user_agent},
                    "Media": {'User-Agent': user_agent}
                },
                "Heartbeat": {
                    "Url": '',
                    "Params": '',
                    "PeriodMs": 5*60*1000
                }
            }
            print(json.dumps(output))
        except Exception as e:
            print(f"Error getting manifest: {e}", file=sys.stderr)
            return "error"

    elif action == "cdm":
        # Televio streams are not DRM protected
        print("Televio streams are not DRM protected", file=sys.stderr)

    else:
        print("invalid action: " + action, file=sys.stderr)

if do_action() == "error":
    login()
    do_action()
