#!/usr/bin/env fuchsia-vendored-python
# Copyright 2023 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.
#
# IMPORTANT: This script should not depend on any Bazel workspace setup
# or specific environment. Only depend on standard Python3 modules
# and assume a minimum of Python3.8 is being used.

"""A tool to perform useful Bazel operations easily."""

import argparse
import os
import re
import subprocess
import sys
from pathlib import Path
from typing import Sequence

def make_bazel_quiet_command(bazel: str, command: str) -> Sequence[str]:
    """Create command argument list for a Bazel command that does not print too much.

    Args:
        bazel: Path to Bazel program.
        command: Bazel command (e.g. 'query', 'build', etc..)
    Returns:
        A sequence of strings that can be used as a command line prefix.
    """
    result = [
      bazel,
      command,
      "--noshow_loading_progress",
      "--noshow_progress",
      "--ui_event_filters=-info",
    ]
    if command != 'query':
      result += [ "--show_result=0" ]
    return result


def cmd_target_dump(args: argparse.Namespace) -> int:
    """Implement the target_dump command."""
    bazel_cmd = make_bazel_quiet_command(args.bazel, 'query') + [ '--output=build' ] + args.target_set
    buildifier_cmd = [args.buildifier, '--type=build', '--mode=fix', '--lint=off']
    proc1 = subprocess.Popen(bazel_cmd, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=None)
    proc2 = subprocess.Popen(buildifier_cmd, stdin=proc1.stdout, stdout=None, stderr=None)
    proc1.wait()
    proc2.wait()
    if proc1.returncode != 0:
      return proc1.returncode
    return proc2.returncode

def cmd_actions(args: argparse.Namespace) -> int:
    """Implement the 'actions' command."""
    bazel_cmd = make_bazel_quiet_command(args.bazel, 'aquery') + args.extra_args[1:] + args.target_set
    print('CMD %s' % bazel_cmd)
    ret = subprocess.run(bazel_cmd, stdin=subprocess.DEVNULL, capture_output=True, text=True)
    if ret.returncode != 0:
      print('%s\n' % ret.stdout, file=sys.stdout)
      print('%s\n' % ret.stderr, file=sys.stderr)
      return ret.returncode

    def ignored_path(path):
        if path.startswith(('external/prebuilt_clang/',
                            'external/fuchsia_clang/',
                            'prebuilt/third_party/sysroot/',)):
            return True

        if path.find('external/fuchsia_prebuilt_rust/') >= 0:
            return True

        return False

    inputs_re = re.compile('^  Inputs: \[(.*)\]$')
    for line in ret.stdout.splitlines():
        m = inputs_re.match(line)
        if m:
            input_paths = []
            for path in m.group(1).split(','):
                path = path.strip()
                if not ignored_path(path):
                    input_paths.append(path)

            line = '  Inputs: [%s]' % (', '.join(input_paths))
        print(line)
    return 0

def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--bazel', default = 'bazel', help='Specify bazel executable')
    parser.add_argument('--buildifier', default = 'buildifier', help='Specify buildifier executable')
    parser.add_argument('--workspace', help='Specify workspace directory')

    subparsers = parser.add_subparsers(help='available commands')

    # The target_dump command.
    parser_target_dump = subparsers.add_parser(
      'target_dump',
      help='Dump definitions of Bazel targets.',
      formatter_class=argparse.RawDescriptionHelpFormatter,
      description=r'''
Print the real definition of a target, or set of targets, in a
Bazel graph, after all macros have been expanded. Note that:

- Each TARGET_SET argument is a standard Bazel target set expression
  (e.g. `//src/lib:foo` or `//:*`).

- The output is pretty printed for readability.

- For each target that is the result of a macro expansion, comments
  are added to descirbe the call chain that led to it.

- For each target generated by native.filegroup() in macros, new
  `generator_{function,location,name}` fields are added to indicate
  how it was generated.
''')
    parser_target_dump.add_argument('target_set', metavar='TARGET_SET', nargs = '+', help='Set of targets to dump.')
    parser_target_dump.set_defaults(func=cmd_target_dump)

    # The target_commands command.
    parser_actions = subparsers.add_parser(
      'actions',
      help='Dump action commands of Bazel targets.',
      formatter_class=argparse.RawDescriptionHelpFormatter,
      description=r'''
Print the action commands of a target, or set of targets, omitting
from the list of inputs sysroot and toolchain related headers, which
can be _very_ long when using the Fuchsia C++ toolchain.
''')
    parser_actions.add_argument('target_set', metavar='TARGET_SET', nargs = '+', help='Set to targets to print actions for.')
    parser_actions.add_argument('--', dest='extra_args', default=[], nargs=argparse.REMAINDER, help='extra Bazel aquery-compatible arguments.')
    parser_actions.set_defaults(func=cmd_actions)

    args = parser.parse_args()
    if args.workspace:
        os.chdir(args.workspace)

    return args.func(args)

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