import sys, json, subprocess

def typst_encode_pre(e, ind="  "):
    if isinstance(e, dict):
        if len(e.items()) == 0:
            return ["(:)"]
        elif len(e.items()) == 1:
            k,v = list(e.items())[0]
            v = typst_encode_pre(v, ind)
            out = ["(" + k + ": " + v[0]]
            out.extend(v[1:])
            out[-1] = out[-1] + ")"
            return out
        else:
            out = ["("]
            first = True
            for k,v in e.items():
                if not first:
                    out[-1] = out[-1] + ","
                first = False
                v = typst_encode_pre(v, ind)
                out.append(ind + k + ": " + v[0])
                out.extend(ind+x for x in v[1:])
                out[-1] = out[-1]
            out.append(")")
            return out
    elif isinstance(e, list):
        if len(e) == 0:
            return ["()"]
        elif len(e) == 1:
            v = typst_encode_pre(e[0], ind)
            out = ["(" + v[0]]
            out.extend(v[1:])
            out[-1] = out[-1] + ")"
            return out
        else:
            out = ["("]
            first = True
            for v in e:
                if not first:
                    out[-1] = out[-1] + ","
                first = False
                v = typst_encode_pre(v, ind)
                out.append(ind + v[0])
                out.extend(ind+x for x in v[1:])
                out[-1] = out[-1]
            out.append(")")
            return out
    elif isinstance(e, bool):
        return ["true" if e else "false"]
    elif isinstance(e, int) or isinstance(e, float):
        return [str(e)]
    elif isinstance(e, str):
        # TODO: can do better (newlines)
        return [json.dumps(e)]
    else:
        raise ValueError(f"can't typst encode {e}")

def typst_encode(e):
    e = typst_encode_pre(e)
    return "\n".join(e)

def typst_query_one(path, tag):
    meta = subprocess.run([
        "typst", "query", path, tag,
        "--one",
        "--field", "value",
        "--root", ".",
        "--input", "query=true",
        "--features", "html"
    ], capture_output=True)
    meta = meta.stdout.decode("utf-8").strip()
    if len(meta) == 0:
        return None
    return json.loads(meta)

out = []
for page in typst_query_one("pages.in.typ", "<articles>"):
    p_page = page["page"]
    p_feed = page["feed"]
    p_homepage = page["homepage"]

    path = f"pages/{p_page}"

    meta = typst_query_one(path, "<feed-ent>")

    last_changed = None
    with open(f"build/{p_page}.git_rev.txt.iso", "r") as f:
        last_changed = f.read().strip()

    res = {
        "url": f"{p_page}.desktop.html",
        "page": p_page,
        "in-feed": p_feed,
        "in-homepage": p_homepage,
        "authors": meta["authors"],
        "title": meta["title"],
        "summary": meta["summary"],
        "modified": last_changed,
    }
    out.append(res)

with open("build/pages.typ", "w") as f:
    f.write("#let articles = " + typst_encode(out) + "\n")

with open("build/pages.json", "w") as f:
    json.dump(out, f)
