import subprocess
import requests
import binascii
import base64
import re
from pywidevine.cdm import Cdm
from pywidevine.device import Device
from pywidevine.pssh import PSSH

MyWVD = "2.wvd"  # File WVD

def get_pssh_from_mpd(mpd_data):
    try:
        # Cerca sia il tag <cenc:pssh> che il tag <pssh> con namespace
        matches = re.findall(r"<(?:cenc:)?pssh.*?>(.*?)</(?:cenc:)?pssh>", mpd_data, re.DOTALL)
        for pssh in matches:
            # Decodifica il PSSH e verifica se contiene il Widevine UUID
            decoded_pssh = base64.b64decode(pssh).hex()
            if "edef8ba9" in decoded_pssh:  # UUID Widevine
                return pssh
        return ''
    except Exception as e:
        print(f"Errore durante l'estrazione del PSSH: {e}")
        return ''
        

def getKeys(url, urlLicence, token):
    # Ottieni il file MPD direttamente dall'URL
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
    }
    response = requests.get(url, headers=headers)
    if response.status_code != 200:
        print(f"Errore nel download del file MPD: {response.status_code}")
        return 'key:nofound'

    # Analizza il contenuto del file MPD
    mpd_data = response.text
    pssh = get_pssh_from_mpd(mpd_data)
    if not pssh:
        print("PSSH non trovato nel file MPD")
        return 'key:nofound'

    pssh_stream = PSSH(pssh)
    device = Device.load(MyWVD)
    cdm = Cdm.from_device(device)
    session_id = cdm.open()
    challenge = cdm.get_license_challenge(session_id, pssh_stream)

    with open("challenge.bin", "wb") as f:
        f.write(challenge)
    
    php_command = ["php", "license_handler.php", token, "challenge.bin", urlLicence]
    try:
        response = subprocess.check_output(php_command)
        license_data = response
        cdm.parse_license(session_id, license_data)
        keys = []
        for key in cdm.get_keys(session_id):
            if key.type != 'SIGNING':
                # Utilizzo corretto di .hex per UUID e bytes
                kid = key.kid.hex  # UUID ha .hex come attributo
                key_value = key.key.hex()  # bytes ha .hex() come metodo
                keys.append(f"{kid}:{key_value}")
        
        cdm.close(session_id)
        return keys
    except subprocess.CalledProcessError as e:
        print(f"Errore nell'esecuzione dello script PHP: {e}")
        cdm.close(session_id)
        return 'key:nofound'

if __name__ == "__main__":
    import sys
    if len(sys.argv) < 4:
        print("Usage: python get_keys.py <MPD_URL> <LICENSE_URL> <TOKEN>")
        sys.exit(1)

    mpd_url = sys.argv[1]
    license_url = sys.argv[2]
    token = sys.argv[3]

    keys = getKeys(mpd_url, license_url, token)

    # Stampa solo le chiavi trovate, una per riga
    if keys != 'key:nofound':
        for key in keys:
            print(key)
    else:
        print("key:nofound")