#!/usr/bin/env python3

import argparse
import contextlib
import os
import pathlib
import shutil
import subprocess as sp
import sys


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--build-dir", type=str, default=".")
    parser.add_argument("--latexusage-name", type=str, default="latexusage")
    parser.add_argument("--latexusage-source-dir", type=str, required=True)
    parser.add_argument("--pdflatex-executable", type=str, default="pdflatex")
    parser.add_argument("--asy-executable", type=str, default="asy")
    parser.add_argument("--asy-base-dir", type=str, required=True)
    return parser.parse_args()


def print_called_process_error(e: sp.CalledProcessError):
    if e.stderr is not None:
        sys.stderr.write("Process stderr:\n")
        sys.stderr.write(e.stderr)

    if e.stdout is not None:
        sys.stderr.write("Process output:\n")
        sys.stderr.write(e.stdout)
    sys.stderr.flush()


def clean_artifacts(buildroot_path: pathlib.Path, latexusage_file_prefix: str):
    if (buildroot_path / (latexusage_file_prefix + ".tex")).is_file():
        os.remove((buildroot_path / (latexusage_file_prefix + ".tex")))
    for asyartifacts in buildroot_path.glob("latexusage-*"):
        os.remove(asyartifacts)
    for exts in ["pre", "aux", "out"]:
        with contextlib.suppress(FileNotFoundError):
            os.remove(buildroot_path / (latexusage_file_prefix + "." + exts))


def run_pdflatex(
    pdflatex_exec: str, buildroot_path: pathlib.Path, latexusage_name: str
):
    sp.run(
        [pdflatex_exec, latexusage_name + ".tex"],
        text=True,
        cwd=buildroot_path,
        check=True,
    )


def main():
    args = parse_args()
    buildroot_path = pathlib.Path(args.build_dir)
    clean_artifacts(buildroot_path, args.latexusage_name)

    # copy latexusage.pdf to build root, since TeX Live has some issues with
    # out of source builds

    shutil.copy2(
        pathlib.Path(args.latexusage_source_dir) / (args.latexusage_name + ".tex"),
        buildroot_path / (args.latexusage_name + ".tex"),
    )

    asy_base_dir = pathlib.Path(args.asy_base_dir)
    asy_base_args = [
        args.asy_executable,
        "-dir",
        str(asy_base_dir),
        "-noprc",
        "-config",
        '""',
        "-render=0",
        "-noV",
    ]

    try:
        # first pdflatex run
        run_pdflatex(args.pdflatex_executable, buildroot_path, args.latexusage_name)
        # asy run
        for asyfile in buildroot_path.glob("latexusage-*.asy"):
            sp.run(
                asy_base_args + [str(asyfile.name)],
                check=True,
                text=True,
                cwd=str(buildroot_path),
            )

        # second pdflatex run
        run_pdflatex(args.pdflatex_executable, buildroot_path, args.latexusage_name)
    except sp.CalledProcessError as e:
        print_called_process_error(e)
        raise
    finally:
        # clean up any latexusage-* files
        clean_artifacts(buildroot_path, args.latexusage_name)


if __name__ == "__main__":
    main()
