#!/usr/bin/env python3

import requests
import re
import time
import json
from pathlib import Path


# ============================================================
# CONFIG
# ============================================================

INPUT_M3U = Path(
    "/opt/epg/megahit.m3u"
)

OUTPUT_M3U = Path(
    "/opt/epg/sk1.m3u")

STREAM_API = (
    "https://api.sweet.tv/TvService/OpenStream.json"
)

# VLOŽ SEM AKTUÁLNY ACCESS TOKEN
# Nikdy sa nezapisuje do M3U.
ACCESS_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2F1dGguc3dlZXQudHYiLCJzdWIiOiIxMDI5MTE0NjUzIiwiZXhwIjoxNzg4NzM4MjY0LCJpYXQiOjE3ODg3Mjc0NjQsImp0aSI6IjYzN2JlODNjLWJiNWEtNDJiZi04ZjYwLWUyMTc5MDNiNDg0NyIsImJpbGxpbmdfaWQiOjEsInByb2ZpbGVfaWQiOiIzVHZ4cFQiLCJkZXZpY2UiOnsidHlwZSI6MjIsImZpcm13YXJlIjp7InZlcnNpb25Db2RlIjoxLCJ2ZXJzaW9uU3RyaW5nIjoiOS4wLjM5In0sInN1Yl90eXBlIjo0MCwibW9kZWwiOiJNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvMTUzLjAuMC4wIFNhZmFyaS81MzcuMzYgRWRnLzE1My4wLjAuMCIsInV1aWQiOiI5NWFhZjAzYi1mMzcyLTQ5YzEtOGY5MC1lYTg2YTIzYjQ2ODciLCJzY3JlZW5faW5mbyI6eyJ3aWR0aCI6MTUzNiwiaGVpZ2h0Ijo4NjQsImFzcGVjdFJhdGlvIjo2fSwiYXBwbGljYXRpb24iOnsidHlwZSI6Mn0sInN1cHBvcnRlZF9kcm0iOnsid2lkZXZpbmVfbW9kdWxhciI6dHJ1ZX0sImRybV9pbmZvIjp7IndpZGV2aW5lX2luZm8iOnsic2VjdXJpdHlfbGV2ZWwiOjN9fX0sImlwIjoiNTEuMTQuNjUuOTUiLCJjb3VudHJ5X2NvZGUiOiJHQiJ9.XIA1OrGEobeovWCYE4d4_iY8u0TQ8xP71OVj_fJAd6w"


USER_AGENT = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/151.0.0.0 Safari/537.36 Edg/151.0.0.0"
)

TIMEOUT = 20
DELAY = 0.15


# ============================================================
# SESSION
# ============================================================

session = requests.Session()

session.headers.update({
    "User-Agent": USER_AGENT,
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "cs,en-GB;q=0.9,en;q=0.8,en-US;q=0.7",
    "Content-Type": "application/json",
    "Origin": "https://sweet.tv",
    "Referer": "https://sweet.tv/",
})


# ============================================================
# PARSE M3U
# ============================================================

def load_channels(filename):

    channels = []

    try:

        with open(
            filename,
            "r",
            encoding="utf-8"
        ) as f:

            for line in f:

                line = line.strip()

                if not line.startswith("#EXTINF:"):
                    continue

                # ------------------------------------------------
                # CID
                # ------------------------------------------------

                cid_match = re.search(
                    r'cid="(\d+)"',
                    line
                )

                if not cid_match:
                    continue

                cid = cid_match.group(1)

                # ------------------------------------------------
                # NAME
                # ------------------------------------------------

                name_match = re.search(
                    r'tvg-name="([^"]*)"',
                    line
                )

                name = (
                    name_match.group(1)
                    if name_match
                    else ""
                )

                # ------------------------------------------------
                # LOGO
                # ------------------------------------------------

                logo_match = re.search(
                    r'tvg-logo="([^"]*)"',
                    line
                )

                logo = (
                    logo_match.group(1)
                    if logo_match
                    else ""
                )

                channels.append({
                    "cid": cid,
                    "name": name,
                    "logo": logo,
                    "extinf": line
                })

    except FileNotFoundError:

        print()
        print("CHYBA: Zdrojový súbor neexistuje:")
        print(filename)
        return []

    except Exception as e:

        print()
        print("CHYBA pri čítaní M3U:")
        print(type(e).__name__, e)
        return []

    return channels


# ============================================================
# OPEN STREAM
# ============================================================

def open_stream(cid, use_bearer=False):

    headers = {}

    if use_bearer and ACCESS_TOKEN:
        headers["Authorization"] = (
            f"Bearer {ACCESS_TOKEN}"
        )

    payload = {
        "channel_id": int(cid),
        "multistream": True,
        "accept_scheme": ["HTTP_HLS"],
   }

    try:

        response = session.post(
            STREAM_API,
            headers=headers,
            json=payload,
            timeout=TIMEOUT
        )

        print(
            f"      HTTP: {response.status_code}"
        )

        try:

            data = response.json()

        except Exception:

            print("      API nevrátilo JSON")
            print(
                response.text[:500]
            )
            return None

        result = data.get("result")
        status = data.get("status")

        print(
            f"      RESULT: {result}  "
            f"STATUS: {status}"
        )

        # ----------------------------------------------------
        # NO AUTH
        # ----------------------------------------------------

        if result == "NoAuth" or status == "NoAuth":

            print(
                "      API RESPONSE: NoAuth"
            )

            return None

        # ----------------------------------------------------
        # OTHER ERROR
        # ----------------------------------------------------

        if result != "OK":

            print(
                "      API RESPONSE:"
            )

            print(
                json.dumps(
                    data,
                    ensure_ascii=False
                )
            )

            return None

        # ----------------------------------------------------
        # HTTP STREAM
        # ----------------------------------------------------

        stream_url = None

        http_stream = data.get(
            "http_stream"
        )

        if isinstance(
            http_stream,
            dict
        ):

            stream_url = (
                http_stream.get("url")
            )

            # ------------------------------------------------
            # RELATIVE URL
            # ------------------------------------------------

            if (
                stream_url
                and stream_url.startswith("/")
            ):

                host = (
                    http_stream.get("host")
                )

                if isinstance(
                    host,
                    dict
                ):

                    address = (
                        host.get("address")
                    )

                    if address:

                        stream_url = (
                            "https://"
                            + address
                            + stream_url
                        )

        # ----------------------------------------------------
        # ALTERNATIVE URL
        # ----------------------------------------------------

        if not stream_url:

            stream_url = data.get(
                "url"
            )

        # ----------------------------------------------------
        # NO URL
        # ----------------------------------------------------

        if not stream_url:

            print(
                "      STREAM URL: NENAJDENÁ"
            )

            return None

        print(
            "      => STREAM OK"
        )

        if data.get("stream_id"):

            print(
                "      STREAM ID:",
                data.get("stream_id")
            )

        print(
            "      URL:",
            stream_url
        )

        return stream_url

    except requests.RequestException as e:

        print(
            "      REQUEST ERROR:",
            e
        )

        return None


# ============================================================
# MAIN
# ============================================================

def main():

    print()
    print("======================================")
    print("SWEET TV UPDATE")
    print("======================================")
    print(
        "INPUT :",
        INPUT_M3U
    )
    print(
        "OUTPUT:",
        OUTPUT_M3U
    )
    print(
        "API   :",
        STREAM_API
    )
    print(
        "Bearer:",
        "ÁNO" if ACCESS_TOKEN else "NIE"
    )
    print("======================================")
    print()

    # ========================================================
    # LOAD M3U
    # ========================================================

    channels = load_channels(
        INPUT_M3U
    )

    if not channels:

        print(
            "Nenašli sa žiadne kanály."
        )

        return

    print(
        "Nájdených kanálov:",
        len(channels)
    )

    print()

    # ========================================================
    # OUTPUT
    # ========================================================

    output = [
        "#EXTM3U"
    ]

    updated = 0
    failed = 0
    noauth_count = 0

    # ========================================================
    # PROCESS CHANNELS
    # ========================================================

    for index, channel in enumerate(
        channels,
        1
    ):

        cid = channel["cid"]
        name = channel["name"]
        extinf = channel["extinf"]

        print(
            "--------------------------------------"
        )

        print(
            f"[{index}/{len(channels)}]"
        )

        print(
            "CID :",
            cid
        )

        print(
            "NAME:",
            name
        )

        # ====================================================
        # 1. WITHOUT BEARER
        # ====================================================

        print(
            "      OpenStream bez Bearer..."
        )

        stream_url = open_stream(
            cid,
            use_bearer=False
        )

        # ====================================================
        # 2. NOAUTH -> BEARER
        # ====================================================

        if not stream_url:

            noauth_count += 1

            if ACCESS_TOKEN:

                print(
                    "      Skúšam Bearer..."
                )

                stream_url = open_stream(
                    cid,
                    use_bearer=True
                )

                if stream_url:

                    print(
                        "      => BEARER FUNGUJE"
                    )

        # ====================================================
        # SAVE
        # ====================================================

        if stream_url:

            output.append(
                extinf
            )

            output.append(
                stream_url
            )

            updated += 1

            print(
                "      => PRIDANÉ DO M3U"
            )

        else:

            failed += 1

            print(
                "      => STREAM FAILED"
            )

            print(
                "      => NEPRIDANÉ DO M3U"
            )

        print()

        time.sleep(
            DELAY
        )

    # ========================================================
    # WRITE M3U
    # ========================================================

    try:

        OUTPUT_M3U.write_text(
            "\n".join(output)
            + "\n",
            encoding="utf-8"
        )

    except Exception as e:

        print()
        print(
            "CHYBA pri zápise M3U:"
        )

        print(
            type(e).__name__,
            e
        )

        return

    # ========================================================
    # SUMMARY
    # ========================================================

    print()
    print("======================================")
    print("HOTOVO")
    print("======================================")

    print(
        "Zdrojových kanálov:",
        len(channels)
    )

    print(
        "Aktualizované     :",
        updated
    )

    print(
        "Neúspešné         :",
        failed
    )

    print(
        "NoAuth            :",
        noauth_count
    )

    print(
        "Výstup            :",
        OUTPUT_M3U
    )

    print("======================================")


# ============================================================
# START
# ============================================================

if __name__ == "__main__":
    main()