#!/usr/bin/env fuchsia-vendored-python
# Copyright 2022 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.

import argparse
import os
import tempfile
import subprocess
import sys
import zipfile

# Wraps a clang-doc invocation for the hermetic build.
#
# Clang-doc generates a directory of output. Since the output file list isn't knowable in advance,
# we need to generate a single archive of the output. This script creates a new empty temp
# directory, runs clang-doc to generate the output, zips that directory to the output, and deletes
# the temporary directory.
#
# Positional arguments are passed directly to clang-doc. Prefix with a "--" to separate them from
# the parameters to this script. Do not include the --output parameter, this will be synthesized
# by this script to point to the temp directory.
#
# Example:
#
#    clang_doc_invoke.py --clang-doc=prebuilt/x64/clang-doc --temp-dir-parent=/tmp
#        --out.zip=output.zip -- --format=yaml --executor=all-TUs --filter=foo.cc
#                                🠭 Args to clang-doc start here.


def main():
    parser = argparse.ArgumentParser(
        "Runs clang-doc in a temporary directory and zips the output.\n"
    )
    parser.add_argument(
        "--clang-doc", help="Path to clang-doc binary.", required=True
    )
    parser.add_argument(
        "--temp-dir-parent",
        help="Parent directory of the unique temp dir to use.",
        required=True,
    )
    parser.add_argument(
        "--out-zip",
        help="Name of the .zip file to create from the clang-doc output.",
        required=True,
    )
    parser.add_argument(
        "clang_doc_args",
        help="Arguments to pass to clang-doc",
        nargs="+",
        metavar="clang-doc-args",
    )
    args = parser.parse_args()

    with tempfile.TemporaryDirectory(dir=args.temp_dir_parent) as temp_dir:
        completed = subprocess.run(
            [args.clang_doc, "--output", temp_dir] + args.clang_doc_args,
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )

        file_count = 0
        with zipfile.ZipFile(args.out_zip, "w") as outfile:
            for root, dirs, files in os.walk(temp_dir):
                for file in files:
                    file_path = os.path.join(root, file)
                    outfile.write(
                        file_path, arcname=os.path.relpath(file_path, temp_dir)
                    )
                    file_count = file_count + 1

        if file_count == 0:
            # Clang-doc doesn't always return nonzero on failure so this is often the failure case.
            print("clang-doc produced no files, failing.")
            print(
                "  This is normally because the target is not in the 'default' build"
            )
            print(
                "  and the fix is to add the cpp_docgen target to your 'universe'."
            )
            print("\nclang-doc output:\n")
            print(bytes.decode(completed.stdout))
            return 1
        return 0


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