#!/usr/bin/env python

import json
import sys

import jinja2
import hcl2

icon_overrides = {
    "acme_dns": "lets-encrypt",
    "backup": "restic",
    "extra_services": None,
    "forgejo_runner": "forgejo",
    "healthcheck": "healthchecks",
    "lego": "lets-encrypt",
    "mailcowdockerized": "mailcow",
    "reitanlage_oranienburg": "grav",
    "tandoor": "tandoor-recipes",
    "tinytinyrss": "tiny-tiny-rss",
    "webdis": "redis",
    "wiki_js": "wiki-js",
}

icon_format = {
    "restic": "webp",
    "linkwarden": "webp",
    "telegraf": "webp",
    "tiny-tiny-rss": "webp",
    "watchtower": "webp", # TODO revert when icon is fixed
}

icon_url = {
    "dokku": "https://avatars.githubusercontent.com/u/13455795?s=200&v=4",
    "factorio": "https://avatars.githubusercontent.com/u/50074624?s=200&v=4",
    "teamspeak_fallback": "https://avatars.githubusercontent.com/u/136759148?s=200&v=4",
    "woodpecker": "https://avatars.githubusercontent.com/u/84780935?s=200&v=4",
}

def get_icon(svc):
    svc = icon_overrides.get(svc, svc) or 'docker'
    fmt = icon_format.get(svc, 'svg')
    return icon_url.get(svc, f'https://cdn.jsdelivr.net/gh/selfhst/icons/{fmt}/{svc}.{fmt}')

def host_key(host, hosts):
    return f"'serguzim.net'.{hosts[host]["provider"]}.{host}"
def service_key(svc, data, hosts):
    return f"{host_key(data["host"], hosts)}.{svc}"


def service_key_find(svc_name, services, hosts):
    if svc := services.get(svc_name):
        return service_key(svc_name, svc, hosts)
    return None

def parse_hosts(hosts):
    result = []
    for host, data in hosts.items():
        result.append({
            'key': host_key(host, hosts),
            'name': host,
        })
    return result

def parse_service(svc, data, hosts):
    svc_key = service_key(svc, data, hosts)

    domains = []
    for dns in data.get("dns") or []:
        domains.append(f"- {dns['domain']}")

    data['name'] = svc
    data['key'] = svc_key
    data['host_key'] = host_key(data["host"], hosts)
    data['label'] = "\\n".join([svc] + domains)
    data['icon'] = get_icon(svc)

    return dict(data)

def parse_services(services, hosts):
    result = []

    postgresql_key = service_key_find("postgresql", services, hosts)
    authentik_key = service_key_find("authentik", services, hosts)

    for svc, data in services.items():
        if data["host"] == "*":
            for host in hosts.keys():
                data["host"] = host
                result.append(parse_service(svc, data, hosts))
        else:
            result.append(parse_service(svc, data, hosts))

    return result

if __name__ == '__main__':
    hosts = {}
    services = {}

    with open('./hosts.auto.tfvars', 'r') as file:
        hosts = hcl2.load(file)["hosts"][0]
    with open('./services.auto.tfvars', 'r') as file:
        services = hcl2.load(file)["services"][0]

    keys = {}
    keys["db_key"] = service_key_find("postgresql", services, hosts)
    keys["db_subkey"] = f"{keys["db_key"]}.dbs"
    keys["auth_key"] = service_key_find("authentik", services, hosts)
    keys["auth_subkey"] = f"{keys["auth_key"]}.apps"
    keys["mail_key"] = service_key_find("mailcowdockerized", services, hosts)
    keys["mail_subkey"] = f"{keys["mail_key"]}.mailboxes"
    keys["monitoring_key"] = service_key_find("gatus", services, hosts)

    jinja_loader = jinja2.FileSystemLoader(searchpath="./templates")
    jinja_env = jinja2.Environment(loader=jinja_loader)
    template = jinja_env.get_template("infrastructure.d2.j2")
    print(template.render(
        grid_svcs=[keys["db_subkey"], keys["auth_subkey"], keys["mail_subkey"]],
        svcs=parse_services(services, hosts),
        hosts=parse_hosts(hosts),
        **keys
    ))