#!/usr/bin/env python3

# Usage: ./app-json.py
#
# Gather metadata from Co-op Cloud apps in $ABRA_DIR/apps (default
# ~/.abra/apps), and format it as JSON so that it can be hosted here:
# https://abra-apps.autonomic.zone

from json import dump
from os import chdir, listdir, mkdir
from os.path import exists, expanduser
from pathlib import Path
from re import findall, search
from shlex import split
from subprocess import check_output, run

from requests import get

HOME_PATH = expanduser("~/")
CLONES_PATH = Path(f"{HOME_PATH}/.abra/apps").absolute()
SCRIPT_PATH = Path(__file__).absolute().parent


def clone_apps():
    if not exists(CLONES_PATH):
        mkdir(CLONES_PATH)

    response = get("https://git.autonomic.zone/api/v1/orgs/coop-cloud/repos")
    repos = [[p["name"], p["ssh_url"]] for p in response.json()]

    skips = ("organising", "cloud.autonomic.zone", "docs.cloud.autonomic.zone", "abra")

    for name, url in repos:
        if name in skips:
            continue

        try:
            if not exists(f"{CLONES_PATH}/{name}"):
                run(split(f"git clone {url} {CLONES_PATH}/{name}"))
                chdir(f"{CLONES_PATH}/{name}")
                if not int(check_output("git branch --list | wc -l", shell=True)):
                    run(split("git checkout main"))
        except Exception:
            pass


def gen_apps_json():
    apps_json = {}

    for app in listdir(CLONES_PATH):
        app_path = f"{CLONES_PATH}/{app}"
        chdir(app_path)

        output = check_output("git tag --list", shell=True)
        tags = output.strip().decode("utf-8")

        if not tags:
            continue

        for tag in tags:
            apps_json[app] = {
                "category": "apps",
                "repository": f"https://git.autonomic.zone/coop-cloud/{app}.git",
                "features": get_app_features(app_path),
                "versions": get_app_versions(app_path),
            }

    return apps_json


def get_app_features(app_path):
    features = {}

    with open(f"{app_path}/README.md", "r") as handle:
        contents = handle.read()

    for match in findall(r"\*\*.*\s\*", contents):
        title = search(r"(?<=\*\*).*(?=\*\*)", match).group().lower()
        if title == "image":
            value = {
                "image": search(r"(?<=`).*(?=`)", match).group(),
                "url": search(r"(?<=\().*(?=\))", match).group(),
                "rating": match.split(",")[1].strip(),
                "source": match.split(",")[-1].replace("*", "").strip(),
            }
        else:
            value = match.split(":")[-1].replace("*", "").strip()
        features[title] = value

    return features


def get_app_versions(app_path):
    versions = {}

    chdir(app_path)
    tags = check_output(f"git tag --list", shell=True).strip()
    for tag in tags:
        # TODO
        # checkout that tag in the local git branch
        # parse all service images via yq or other magic
        # lookup the digest with skopeo
        pass

    return versions


clone_apps()

target = f"{SCRIPT_PATH}/../deploy/abra-apps.autonomic.zone/abra-apps.json"
with open(target, "w", encoding="utf-8") as handle:
    dump(gen_apps_json(), handle, ensure_ascii=False, indent=4)

print(f"Output saved to {target}")