#!/usr/bin/env fuchsia-vendored-python
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generate FIDL reference docs for one or more Fuchsia packages.

This script uses fidldoc which documents FIDL libraries passed in via
a .txt file.
"""

import argparse
import json
import os
import shutil
import subprocess
import sys


def walk_rmtree(directory):
    """Manually remove all subdirectories and files of a directory
    via os.walk instead of using
    shutil.rmtree, to avoid registering spurious reads on stale
    subdirectories. See https://fxbug.dev/42153728.

    Args:
        directory: path to directory which should have tree removed.
    """
    for root, dirs, files in os.walk(directory, topdown=False):
        for file in files:
            os.unlink(os.path.join(root, file))
        for dir in dirs:
            full_path = os.path.join(root, dir)
            if os.path.islink(full_path):
                os.unlink(full_path)
            else:
                os.rmdir(full_path)
    os.rmdir(directory)


def read_fidl_packages(build_dir):
    fidldoc = os.path.join(build_dir, "sdk_fidl_json.json")
    with open(fidldoc, "r") as fdl_json:
        fidl_pkgs = json.load(fdl_json)
    return [pkg["ir"] for pkg in fidl_pkgs]


def run_fidl_doc(build_dir, out_dir, fidl_files, zipped_result=False):
    fidldoc_path = os.path.join(build_dir, "host-tools", "fidldoc")
    out_fidl = os.path.join(out_dir, "fidldoc")
    gen_fidl = subprocess.run(
        [
            fidldoc_path,
            "--silent",
            "--path",
            "/reference/fidl/",
            "--out",
            out_fidl,
        ]
        + fidl_files
    )

    if gen_fidl.returncode:
        print(gen_fidl.stderr)
        return 1

    if zipped_result:
        shutil.make_archive(
            os.path.join(out_dir, "fidldoc"),
            "zip",
            root_dir=out_dir,
            base_dir="fidldoc",
        )
        walk_rmtree(out_fidl)


def main():
    parser = argparse.ArgumentParser(
        description=__doc__,  # Prepend help doc with this file's docstring.
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "-z",
        "--zipped-result",
        action="store_true",
        help=(
            "If set will zip output documentation and delete md files."
            "This is to make the doc generation process hermetic"
        ),
    )
    parser.add_argument(
        "--dep-file", type=argparse.FileType("w"), required=True
    )
    parser.add_argument(
        "-o",
        "--out-dir",
        type=str,
        required=True,
        help="Output location where generated docs should go",
    )
    parser.add_argument(
        "-b",
        "--build-dir",
        type=str,
        required=True,
        help="Directory location of previously built artifacts",
    )

    args = parser.parse_args()
    input_fidl_files = read_fidl_packages(args.build_dir)
    args.dep_file.write(
        "{}: {}\n".format(
            os.path.join(args.out_dir, "fidldoc.zip"),
            " ".join(input_fidl_files),
        )
    )
    run_fidl_doc(
        args.build_dir, args.out_dir, input_fidl_files, args.zipped_result
    )


if __name__ == "__main__":
    sys.exit(main())
