#!/usr/bin/env python3

import json
import os
import re

from androguard.core.bytecodes.apk import APK, get_apkid
import requests
import yaml

import apkpure
import evozi


with open("apps.yml" ,'r') as f:
    apps = yaml.safe_load(f)

def download():
    for app_id, app in apps.items():
        print(app_id)
        if "download" in app:
            r = requests.get(app["download"])
            r.raise_for_status()
            match = re.search(r"^.*(https?://.+?\.apk).*$", r.text)
            apk_url = match.groups()[0]

            r = requests.get(apk_url)
            r.raise_for_status()
            apk_data = r.content
            print(f"Downloaded from {apk_url}")

        else:
            try:
                apk_data = apkpure.get(app_id)
                print(f"Downloaded from apkpure.com")
            except apkpure.DownloadError:
                apk_data = evozi.get(app_id)
                print(f"Downloaded from apps.evozi.com")

        apk = APK(apk_data, raw=True)
        if not apk.valid_apk:
            raise RuntimeError("No valid apk downloaded!")

        # check certificate fingerprint
        if "fingerprint" in app:
            certs = apk.get_certificates()
            if len(certs) != 1:
                raise RuntimeError("There should be exactly one certificate in apk.")
            fingerprint = certs[0].sha256_fingerprint.lower().replace(' ','')
            if fingerprint != app["fingerprint"]:
                raise RuntimeError("Certificate fingerprint doesn't match.")
        else:
            print("Skipping certificate fingerprint check.")

        # save apk
        version = apk.get_androidversion_name()
        code = apk.get_androidversion_code()
        os.makedirs("fdroid/repo", exist_ok=True)
        path = f"fdroid/repo/{app_id}_{code}_{version}.apk"
        with open(path, "wb") as f:
            f.write(apk_data)
        print(f"Done. Saved to {path}.")

        # write metadata yaml
        if "metadata" in app:
            os.makedirs("fdroid/metadata", exist_ok=True)
            with open(f"fdroid/metadata/{app_id}.yml", 'w') as f:
                yaml.dump(app["metadata"], f)
            print(f"Metadata written to fdroid/metadata/{app_id}.yml.")

if __name__ == "__main__":
    download()
