#!/usr/bin/env python3
#
# Copyright (c) 2024 Rackslab
#
# This file is part of RacksDB.
#
# SPDX-License-Identifier: GPL-3.0-or-later

import sys
import yaml
from pathlib import Path

from rfl.build.ninja import NinjaBuilder
from rfl.build.projectversion import project_version

# Sizes names and associated DPI
SVG_SIZES = {"tiny": 32, "small": 64, "medium": 96, "large": 128, "xlarge": 192}
TARGETS = ["all", "man", "schema-ref", "drawing-ref", "openapi", "png", "clean"]
MANPAGE_SOURCE = f"RacksDB {project_version()}"
DOCS_DIR = Path(__file__).parent
RACKSDB_SCHEMA = DOCS_DIR.parent / "schemas/racksdb.yml"
RACKSDB_REF = DOCS_DIR / "modules/db/partials/objects.adoc"
DRAWINGS_SCHEMA = DOCS_DIR.parent / "schemas/drawings.yml"
DRAWINGS_REF = DOCS_DIR / "modules/usage/partials/drawing-objects.adoc"
OPENAPI = DOCS_DIR / "modules/usage/attachments/openapi.yml"


def main():
    targets = sys.argv[1:]

    if any([target not in TARGETS for target in targets]):
        print(f"Supported targets are: {TARGETS}")
        sys.exit(1)

    if not (len(targets)):
        targets = ["all"]

    builder = NinjaBuilder()

    with open(DOCS_DIR / "utils/build.yaml") as fh:
        rules = yaml.safe_load(fh.read())

    # clean target
    if "clean" in targets:
        manpages = (DOCS_DIR / "man").glob("*.1")
        for manpage in manpages:
            print(f"Removing manpage {manpage}")
            manpage.unlink()
        generated_pngs = [
            (DOCS_DIR / svg_s).with_suffix(".png") for svg_s in rules["diagrams"].keys()
        ]
        for generated_png in generated_pngs:
            print(f"Removing generated PNG image {generated_png}")
            generated_png.unlink()
        print(f"Removing RacksDB schema reference documentation {RACKSDB_REF}")
        RACKSDB_REF.unlink()
        print(f"Removing RacksDB drawing schema reference documentation {DRAWINGS_REF}")
        DRAWINGS_REF.unlink()
        print(f"Removing OpenAPI description {OPENAPI}")
        OPENAPI.unlink()

    for size, dpi in SVG_SIZES.items():
        builder.rule(
            name=f"png-{size}",
            command=(
                f"inkscape $in --export-type=png --export-overwrite --export-dpi={dpi} "
                "--export-filename=$out"
            ),
        )

    builder.rule(
        name="manpage",
        command=(
            f"asciidoctor --backend manpage --attribute mansource='{MANPAGE_SOURCE}' "
            "$in"
        ),
    )

    builder.rule(name="schema-ref", command="python3 utils/schema-objs.py > $out")

    builder.rule(
        name="drawing-ref", command="python3 utils/drawings-schema-objs.py > $out"
    )
    builder.rule(name="openapi", command="python3 utils/gen-openapi.py > $out")

    if "man" in targets or "all" in targets:
        manpages = (DOCS_DIR / "man").glob("*.adoc")
        for manpage in manpages:
            implicit = DOCS_DIR / "modules/usage/pages" / manpage.name
            target = (DOCS_DIR / "man" / manpage.stem).with_suffix(".1")
            builder.build(
                outputs=[target], rule="manpage", inputs=[manpage], implicit=[implicit]
            )

    if "schema-ref" in targets or "all" in targets:
        builder.build(
            outputs=[RACKSDB_REF], rule="schema-ref", implicit=[RACKSDB_SCHEMA]
        )

    if "drawing-ref" in targets or "all" in targets:
        builder.build(
            outputs=[DRAWINGS_REF], rule="drawing-ref", implicit=[DRAWINGS_SCHEMA]
        )

    if "openapi" in targets or "all" in targets:
        builder.build(
            outputs=[OPENAPI],
            rule="openapi",
            implicit=[RACKSDB_SCHEMA, DRAWINGS_SCHEMA],
        )

    if "png" in targets or "all" in targets:
        svg_rules = rules["diagrams"]
        for svg_s, size in svg_rules.items():
            svg = DOCS_DIR / svg_s
            png = svg.with_suffix(".png")
            builder.build(outputs=[png], rule=f"png-{size}", inputs=[svg])

    builder.run()


if __name__ == "__main__":
    main()
