#!/usr/bin/env fuchsia-vendored-python
# Copyright 2019 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.
"""
Example usage:
$ fx set ...
$ scripts/gn/suppress_errors.py --issue=-Wshorten-64-to-32 --issue=-Wimplicit-int-float-conversion --config="//build/config:Wno-conversion"
"""

import argparse
import fileinput
import multiprocessing
import os
import re
import subprocess
import json
import sys
import functools
from typing import List, Dict


def run_command(command):
    return subprocess.check_output(
        command, stderr=subprocess.STDOUT, encoding="utf8"
    )


# functools.cache is more semantically accurate, but requires Python 3.9
@functools.lru_cache
def get_out_dir():
    """Retrieve the build output directory"""

    fx_status = run_command(["fx", "status", "--format=json"])
    return json.loads(fx_status)["environmentInfo"]["items"]["build_dir"][
        "value"
    ]


def get_common_gn_args():
    """Retrieve common GN args shared by several commands in this script.
    Returns:
      A list of GN command-line arguments (to be used after "gn <command>").
    """

    return [get_out_dir()]


def gn_find_refs(files: List[str], raise_if_no_match: bool = True) -> List[str]:
    """Wrapper around `fx gn refs`.

    Returns the targets referencing any of the files in `error_files`.
    """
    refs_command = ["fx", "gn", "refs"]
    refs_command += get_common_gn_args()
    refs_command += sorted(files)
    try:
        refs_out = run_command(refs_command)
    except subprocess.CalledProcessError as e:
        if (
            "The input matches no targets, configs, or files." in e.output
            and not raise_if_no_match
        ):
            return []
        print(f"Failed to resolve references for {files}!", file=sys.stderr)
        print(e.output, file=sys.stderr)
        raise e
    return refs_out.splitlines()


def gn_find_refs_complete(
    path: str, sources_that_include_header: Dict[str, List[str]]
) -> List[str]:
    """Returns the targets referencing a path.
    If no targets refer to that path and the path is a header,
    fallback to looking for the targets that reference the source files which
    include that header.
    If still no targets, return an empty list.

    This function is module-level for reasons to do with how Python
    multiprocessing works.

    Args:
      params: tuple of (path, dictionary from header to list of sources)
    """

    refs = gn_find_refs([path], raise_if_no_match=False)
    if refs:
        return refs

    # If no direct reference, look for refs for the sources instead.
    print(
        f"Note: looking for source files which includes {path}, "
        "because the path was not tracked by the build system",
        file=sys.stderr,
    )
    sources = sources_that_include_header.get(path, [])
    if not sources:
        print(
            f"Warning: {path} was not tracked by the build system, "
            "and not included by any sources",
            file=sys.stderr,
        )
        return []
    return gn_find_refs(sources)


def can_have_config(params):
    """Returns whether the given target can have a config.
    If not sure, returns True.

    This function is module-level for reasons to do with how Python
    multiprocessing works.

    Args:
      params: tuple of target to examine, config to add.
              Packed in a single tuple for reasons to do with how Python
              multiprocessing works.
    """

    (
        target,
        config,
    ) = params

    desc_command = ["fx", "gn", "desc"]
    desc_command += get_common_gn_args()

    try:
        desc_out = run_command(desc_command + [target, "configs"])
        # Target has configs and they include the given config.
        # Can't add a duplicate config!
        return config not in desc_out
    except subprocess.CalledProcessError as e:
        if 'Don\'t know how to display "configs" for ' in e.output:
            # Target type cannot have configs,
            # or the actual target is in another toolchain.
            # Assume the latter.
            return True
        elif " matches no targets, configs or files" in e.output:
            # The target probably exists in a non-default toolchain.
            # Assume that it can have the config.
            return True
        else:
            raise e


included_from_regex = re.compile("In file included from (.*?\.(c|cc|cpp)):\d*")


def find_cc_file_using_included_from(prev_lines: str):
    """Given the last lines of compiler output, find the first path that
    is not of the 'In file included from ...' format, which is probably the
    source file that led to the error by including a chain of headers.
    """
    # The last line should be a header file reference
    assert (
        "In file included from" not in prev_lines[-1]
    ), f"unexpected {prev_lines}"
    # Go backwards until we hit a '.cc' or '.cpp' file
    for l in reversed(prev_lines[:-1]):
        match = included_from_regex.match(l)
        if match:
            return os.path.normpath(os.path.join(get_out_dir(), match.group(1)))
    raise RuntimeError(f"Cannot find .cc/.cpp file in {prev_lines}")


def main():
    parser = argparse.ArgumentParser(
        description="Adds a given config to all compile targets with "
        "a given compiler error"
    )
    parser.add_argument(
        "--fx-build-log",
        help="Captured output from a build invocation. "
        "If not provided, the tool will invoke the build first.",
    )
    parser.add_argument(
        "--confirm",
        help="If true, pause after each step in the script to review changes",
        action=argparse.BooleanOptionalAction,
        default=False,
    )
    parser.add_argument(
        "--complete",
        help="If true, attempt to produce a complete annotation by attributing errors "
        "in unreferenced headers to source files that include that header.",
        action=argparse.BooleanOptionalAction,
        default=False,
    )
    parser.add_argument(
        "--issue",
        action="append",
        required=True,
        help="A regex matching the intended compiler error/warning. "
        "E.g. --issue='error:.*-Wconversion'."
        "Take care to avoid character expansion by the shell, for example "
        "by using single quotation marks.",
    )
    parser.add_argument("--config", required=True, help="GN config to add")
    parser.add_argument("--comment", help="Comment to add before config")
    args = parser.parse_args()
    fx_build_log = args.fx_build_log
    confirm = args.confirm
    complete = args.complete
    issue = "|".join(args.issue)
    config = args.config
    comment = args.comment

    log_regex = re.compile(f"(?:\.\./)*([^:]*):\d*:\d*:.*({issue})")

    if fx_build_log:
        with open(fx_build_log, "r") as f:
            build_out = f.readlines()
    else:
        # Harvest all compilation errors
        print("Building...")
        try:
            # On error continue building to discover all failures
            build_out = run_command(["fx", "build", "-k0"])
        except subprocess.CalledProcessError as e:
            build_out = e.output
        build_out = build_out.splitlines()

    sources_that_include_header = {}
    error_files = set()
    prev_lines = []
    for line in build_out:
        prev_lines.append(line)
        # We probably won't have more than 30 layers of header inclusions.
        prev_lines = prev_lines[-30:]
        match = log_regex.match(line)
        if match:
            path = os.path.normpath(match.group(1))
            if path.endswith(".h"):
                # Trace back to a '.cc' file, and record on the side
                sources = sources_that_include_header.get(path, [])
                sources.append(find_cc_file_using_included_from(prev_lines))
                sources_that_include_header[path] = sources
            error_files.add(path)
    print("Sources with compilation issues:")
    print("\n".join(sorted(error_files)))
    print()
    if not error_files:
        return 0
    if confirm:
        input("Press Enter to continue...")

    # Collect all BUILD.gn files with targets referencing failing sources
    print("Resolving references...")
    target_no_toolchain = re.compile("(\/\/[^:]*:[^(]*)(?:\(.*\))?")
    if complete:
        # Run `gn ref` on every error file individually. This is the only way
        # we can determine if a certain file does not have a reference.
        # Cap the max parallelism as the `gn refs` operation turned out very
        # memory intensive.
        with multiprocessing.Pool(min(multiprocessing.cpu_count(), 20)) as p:
            refs_lists = p.starmap(
                gn_find_refs_complete,
                ((path, sources_that_include_header) for path in error_files),
            )
            error_targets = {
                target_no_toolchain.match(ref).group(1)
                for refs in refs_lists
                for ref in refs
            }
    else:
        # Use a single `gn refs` invocation to find all references.
        # Note that this may silently omit files without references.
        refs_out = gn_find_refs(error_files)
        error_targets = {
            target_no_toolchain.match(ref).group(1) for ref in refs_out
        }
    print("Targets with the error:")
    print(error_targets)
    print()
    if confirm:
        input("Press Enter to continue...")

    # Remove targets that already have the given config
    # or can't have a config in the first place
    print("Removing irrelevant targets...")
    # `gn desc` is slow so parallelize
    # cap the max parallelism as the `gn refs` operation turned out very
    # memory intensive.
    with multiprocessing.Pool(min(multiprocessing.cpu_count(), 20)) as p:
        target_can_have = zip(
            error_targets,
            p.map(
                can_have_config, ((target, config) for target in error_targets)
            ),
        )
        error_targets = {
            target for target, can_have in target_can_have if can_have
        }

    print("Failing targets:")
    print("\n".join(sorted(error_targets)))
    print()
    if confirm:
        input("Press Enter to continue...")

    # Fix failing targets
    ref_regex = re.compile("//([^:]*):([^.(]*).*")
    for target in sorted(error_targets):
        match = ref_regex.match(target)
        build_dir, target_name = match.groups()
        target_regex = re.compile(
            '^\s*\w*\("' + re.escape(target_name) + '"\) {'
        )
        build_file = os.path.join(build_dir, "BUILD.gn")
        # Format file before processing
        run_command(["fx", "format-code", "--files=" + build_file])
        print("Fixing", target)
        in_target = False
        config_printed = False
        in_configs = False
        curly_brace_depth = 0
        secondary_build_file = os.path.join("build", "secondary", build_file)
        if os.path.exists(secondary_build_file):
            # Sometimes we put third_party BUILD.gn files in a shadow directory
            # to avoid conflicting with original BUILD.gn files.
            build_file = secondary_build_file
        start_configs_inline = re.compile('configs \+?= \[ "')
        start_configs = re.compile("configs \+?= \[")

        for line in fileinput.FileInput(build_file, inplace=True):
            curly_brace_depth += line.count("{") - line.count("}")
            assert curly_brace_depth >= 0
            if config_printed:
                # We already printed the config, keep running until we exit the target
                if curly_brace_depth == target_end_depth:
                    in_target = False
            elif not in_target:
                # Try to enter target
                in_target = bool(target_regex.match(line))
                if in_target:
                    target_end_depth = curly_brace_depth - 1
            elif curly_brace_depth > target_end_depth + 1:
                # Ignore inner blocks such as inner definitions and conditionals
                pass
            elif curly_brace_depth == target_end_depth:
                # Last chance to print config before exiting
                if comment:
                    print("#", comment)
                print('configs += [ "' + config + '"]')
                config_printed = True
                in_target = False
            elif start_configs_inline.match(line) and config in line:
                config_printed = True
            elif start_configs_inline.match(line):
                line = line[:-3] + ', "' + config + '" ]\n'
                config_printed = True
            elif start_configs.match(line):
                in_configs = True
            elif in_configs and line.strip() == '"' + config + '",':
                in_configs = False
                config_printed = True
            elif in_configs and line.strip() == "]":
                if comment:
                    print("#", comment)
                print('"' + config + '",')
                in_configs = False
                config_printed = True
            print(line, end="")
            if config_printed and not in_target:
                # Reset for a possible redefinition of the same target
                # (e.g. within another conditional block)
                config_printed = False
        run_command(["fx", "format-code", "--files=" + build_file])

    print("Fixed all of:")
    for error_target in sorted(error_targets):
        print('  "' + error_target + '",')

    return 0


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