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

from __future__ import print_function

import argparse
import os.path
import sys

# Exempt targets with these prefixes.
EXEMPTION_PREFIXES = [
    # TODO(https://fxbug.dev/42134670): cargo-gnaw should generate sources files for third party crates.
    "//third_party/rust_crates:",
]


def parse_depfile(depfile_path):
    with open(depfile_path) as f:
        # Only the first line contains important information.
        line = f.readline().strip()

    # The depfile format looks like `target: dep1 dep2 dep3...`
    # We assume the target is the one we care about and that dep1, dep2, dep3, etc. are
    # source files.
    #
    # We use `os.path.relpath` to convert paths like '../../out/default/foo/bar' to the
    # canonical 'foo/bar', which is how the expected inputs are expressed.
    return set(
        os.path.relpath(os.path.normpath(source))
        for source in line[line.find(":") + 1 :].split(" ")
        if source.strip()
    )


def build_file_source_path(target, source_path):
    """Returns a source path suitable for listing in a BUILD.gn file.

    The returned path is relative to the `target` GN label, or source absolute if the
    `source_path` is not a descendent of the `target`.

    Eg. for `target` of '//src/sys/component_manager:bin':
      when source_path='../../src/sys/component_manager/src/main.rs'
        return 'src/main.rs'
      when source_path='../../prebuilts/assets/font.ttf'
        return '//prebuilts/assets/font.ttf'
    """
    while source_path.startswith("../"):
        source_path = source_path[3:]
    target_dir = target[2:].split(":")[0]
    if source_path.startswith(target_dir):
        return os.path.relpath(source_path, start=target_dir)
    return "//{}".format(source_path)


def print_suggested_sources(varname, sources):
    """Prints a GN list variable assignment with the variable name `varname`.

    Eg.

      sources = [
        "src/main.rs",
        "src/foo.rs",
      ]
    """
    print("  {} = [".format(varname), file=sys.stderr)
    for source in sources:
        print('    "{}",'.format(source), file=sys.stderr)
    print("  ]", file=sys.stderr)


def main():
    parser = argparse.ArgumentParser(
        description="Verifies that the compiler-emitted depfile strictly contains the expected source files"
    )
    parser.add_argument(
        "-t",
        "--target_label",
        required=True,
        help="GN target label being checked",
    )
    parser.add_argument(
        "-d",
        "--depfile",
        required=True,
        help="path to compiler emitted depfile",
    )
    parser.add_argument(
        "expected_sources",
        nargs="*",
        help="path to the expected list of source files",
    )
    args = parser.parse_args()

    # Check for opt-out.
    if args.expected_sources and args.expected_sources[0].endswith(
        "/build/rust/__SKIP_ENFORCEMENT__.rs"
    ):
        return 0

    # Ignore specific target exemptions.
    for prefix in EXEMPTION_PREFIXES:
        if args.target_label.startswith(prefix):
            return 0

    expected_sources = set(args.expected_sources)
    actual_sources = parse_depfile(args.depfile)

    unlisted_sources = actual_sources.difference(expected_sources)
    if unlisted_sources:
        # There is a mismatch in expected sources and actual sources used by the compiler.
        # We don't treat overly-specified sources as an error. Ninja will still complain
        # if those source files don't exist.
        for source in unlisted_sources:
            print(
                "error: source file `{}` was used during compilation but not listed in BUILD.gn".format(
                    source
                ),
                file=sys.stderr,
            )

        print(
            "note: the BUILD.gn file for {} should have the following:\n".format(
                args.target_label
            ),
            file=sys.stderr,
        )

        rust_sources = [
            build_file_source_path(args.target_label, source)
            for source in actual_sources
            if source.endswith(".rs")
        ]
        if rust_sources:
            print_suggested_sources("sources", rust_sources)

        non_rust_sources = [
            build_file_source_path(args.target_label, source)
            for source in actual_sources
            if not source.endswith(".rs")
        ]
        if non_rust_sources:
            print_suggested_sources("inputs", non_rust_sources)

        return 1
    return 0


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