#!/usr/bin/env python3
# Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# This program executes Dart programs on RBE using rewrapper by parsing the
# source code to locate the input files, and recognizes the command line options
# of well known programs to determine the output files.

# New executions during the Dart SDK build needs to be supported here in order
# to speed up the build with RBE. See the argument parser below.

import json
import os
import re
import subprocess
import sys


# Run a command, swallowing the output unless there is an error.
def run_command(command, strategy):
    try:
        subprocess.check_output(command, stderr=subprocess.STDOUT)
        return 0
    except subprocess.CalledProcessError as e:
        print(e.output.decode("utf-8"))
        if strategy == 'remote':
            joined = ' '.join(command)
            print(f'''Failed to run command remotely: {joined}

If you're seeing this error on a bot and it doesn't happen locally, then you may
need to teach the script build/rbe/rewrapper_dart.py what the appropriate input
and outputs files of the command are. You can see the list of used inputs and
outputs in the rewrapper invocation above. To reproduce this error locally, try
forcing a remote build by setting the RBE_exec_strategy=remote environment
variable.
''')
        sys.exit(1)
    except OSError as e:
        print(e.strerror)
        sys.exit(1)


# Loads the package config file.
def load_package_config(exec_root):
    path = os.path.join(exec_root, '.dart_tool', 'package_config.json')
    with open(path, 'r') as file:
        return json.load(file)


# Resolves a Dart import URI using the package config.
def resolve_uri(uri, exec_root, package_config, whole_dir=False):
    if uri.startswith('package:'):
        match = re.search(r'package:([^/]*)/(.*)', uri)
        package_name = match.groups()[0]
        relative = match.groups()[1]
        package_data = next(pkg for pkg in package_config['packages']
                            if pkg['name'] == package_name)
        package_root = package_data['rootUri']
        package_root = package_root[3:]  # Remove leading ../
        package_uri = package_data['packageUri']
        if whole_dir:
            uri = package_root + '/' + package_uri
        else:
            uri = package_root + '/' + package_uri + relative
    return uri


# Lists the imports of a Dart file uri using the package config and a rough
# parser that recognizes fairly traditional imports. This is designed to be much
# faster than actually invoking the front end.
def list_imports(uri, exec_root, package_config):
    if uri.startswith('dart:'):
        return set()
    path = os.path.join(exec_root, resolve_uri(uri, exec_root, package_config))
    file = open(path, 'r')
    imports = set()
    for line in file.readlines():
        tokens = [token for token in re.split(r'\s+', line) if token != '']
        if not tokens or tokens[0] in [
                '//', '///', '/*', '*/', '#!', 'library', 'show'
        ]:
            continue
        # Imports must happen before definitions.
        if tokens[0] in ['const', 'class', 'enum']:
            break
        if 2 <= len(tokens
                   ) and tokens[0] == 'if' and tokens[1] == '(dart.library.io)':
            tokens = ['import'] + tokens[2:]
        if tokens[0] not in ['import', 'export', 'part']:
            continue
        if len(tokens) < 2:
            raise Exception(f'Bad import statement: {path}: {line}')
        if tokens[0] == 'part' and tokens[1] == 'of':
            continue
        token = tokens[1].replace('"', '').replace("'", '').replace(';', '')
        if token.startswith('dart:'):
            continue
        if not ':' in token:
            dirname = os.path.dirname(uri)
            while token.startswith('..'):
                token = token[3:]
                dirname = os.path.dirname(dirname)
            token = dirname + '/' + token
        imports.add(token)
    file.close()
    return imports


# Transitively compute the set of dart files needed to execute the specified
# entry point using the package config.
def find_inputs(uris, exec_root, package_config):
    inputs = set(uris)
    unexplored = set(uris)
    while unexplored:
        uri = unexplored.pop()
        imports = list_imports(uri, exec_root, package_config)
        for uri in imports:
            if not uri in inputs:
                inputs.add(uri)
                unexplored.add(uri)
    return inputs


# Rewrite absolute paths in an argument to be relative.
def rewrite_absolute(arg, exec_root, working_directory):
    # The file:// schema does not work with relative paths as they are parsed as
    # the authority by the dart Uri class.
    arg = arg.replace('file:///' + exec_root, '../../')
    arg = arg.replace('file://' + exec_root, '../../')
    # Replace the absolute exec root by a relative path to the exec root.
    arg = arg.replace(exec_root, '../../')
    # Simplify paths going to the exec root and back into the out directory.
    # Carefully ensure the whole path isn't optimized away.
    if arg.endswith(f'../../{working_directory}/'):
        arg = arg.replace(f'../../{working_directory}/', '.')
    else:
        arg = arg.replace(f'../../{working_directory}/', '')
    return arg


# Parse the command line execution to recognize well known programs during the
# Dart SDK build, so the inputs and output files can be determined, and the
# command can be offloaded to RBE.
#
# RBE needs a command to run, a list of input files, and a list of output files,
# and it then executes the command remotely and caches the result. Absolute
# paths must not occur in the command as the remote execution will happen in
# another directory. However, since we currently rely on absolute paths, we work
# around the issue and rewrite the absolute paths accordingly until the problem
# is fixed on our end.
#
# This is a parser that handles nested commands executing each other, taking
# care to know whose options it is currently parsing, and extracting the
# appropriate information from each argument. Every invoked program and option
# during the build needs to be supported here, otherwise the remote command may
# be inaccurate and not have right inputs and outputs. Although maintaining this
# parser takes some effort, it is being paid back in the builders being sped up
# massively on cache hits, as well as speeding up any local developers that
# build code already built by the bots.
#
# To add a new program, recognize the entry point and define its parser method.
# To add a new option, parse the option in the appropriate method and either
# ignore it or recognize any input and output files. All invoked options needs
# be allowlisted here know we didn't accidentally misunderstand the invoked
# command when running it remotely.
class Rewrapper:

    def __init__(self, argv):
        self.dart_subdir = None
        self.depfiles = None
        self.entry_points = set()
        self.exec_root = None
        self.exec_strategy = 'remote'
        self.exec_strategy_explicit = False
        self.extra_paths = set()
        self.outputs = []
        self.no_remote = None
        self.argv = argv
        self.optarg = None
        self.optind = 0
        self.parse()

    @property
    def has_next_arg(self):
        return self.optind + 1 < len(self.argv)

    def next_arg(self):
        self.optind += 1
        return self.argv[self.optind]

    def get_option(self, options):
        arg = self.argv[self.optind]
        for option in options:
            if arg == option:
                self.optind += 1
                self.optarg = self.argv[self.optind]
                return True
            elif option.startswith('--') and arg.startswith(f'{option}='):
                self.optarg = arg[len(f'{option}='):]
                return True
            elif option[0] == '-' and option[1] != '-' and arg.startswith(
                    option):
                self.optarg = arg[len(option):]
                return True
        return False

    def unsupported(self, state, arg):
        raise Exception(f'''Unsupported operand in state {state}: {arg}

You need to recognize the argument/option in the build/rbe/rewrapper_dart.py
script in order to execute this command remotely on RBE. Read the big comments
in the file explaining what this script is and how it works. Follow this stack
trace to find the place to insert the appropriate support.
''')

    def rebase(self, path):
        if path.startswith('package:'):
            return path
        # Handle the use of paths starting with an extra slash.
        if path.startswith('org-dartlang-kernel-service:///'):
            path = os.path.join(self.exec_root,
                                path[len('org-dartlang-kernel-service:///'):])
        if path.startswith('org-dartlang-kernel-service://'):
            path = os.path.join(self.exec_root,
                                path[len('org-dartlang-kernel-service://'):])
        # Handle the use of paths starting with an extra slash.
        if path.startswith('file:////'):
            path = path[len('file:///'):]
        elif path.startswith('file://'):
            path = path[len('file://'):]
        path = os.path.abspath(path)
        if not path.startswith(self.exec_root):
            raise Exception(f"Path isn't inside exec_root: {path}")
        return path[len(self.exec_root):]

    def parse(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg == 'rewrapper' or arg.endswith('/rewrapper'):
                return self.parse_rewrapper()
            else:
                self.unsupported('rewrapper_dart', arg)

    def parse_rewrapper(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['--cfg']):
                with open(self.optarg, 'r') as fp:
                    for line in fp.readlines():
                        key, value = fp.split('=')
                        if key == 'exec_root':
                            self.exec_root = value
                        elif key == 'exec_strategy':
                            self.exec_strategy = value
            elif self.get_option(['--exec_root']):
                self.exec_root = os.path.abspath(self.optarg)
                if not self.exec_root.endswith('/'):
                    self.exec_root += '/'
            elif self.get_option(['--exec_strategy']):
                self.exec_strategy = self.optarg
                self.exec_strategy_explicit = True
            elif arg == '--':
                env_exec_strategy = os.environ.get('RBE_exec_strategy')
                if env_exec_strategy and not self.exec_strategy_explicit:
                    self.exec_strategy = env_exec_strategy
            elif arg.startswith('-'):
                pass  # Ignore unknown rewrapper options.
            elif arg.endswith('/dart'):
                self.dart_subdir = os.path.dirname(arg)
                return self.parse_dart()
            elif arg.endswith('/gen_snapshot') or arg.endswith(
                    '/gen_snapshot_product'):
                return self.parse_gen_snapshot()
            else:
                self.unsupported('rewrapper', arg)

    def parse_dart(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['--dfe']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option(['--snapshot']):
                self.outputs.append(self.rebase(self.optarg))
            elif self.get_option(['--depfile']):
                self.depfiles = [self.rebase(self.optarg)]
            elif self.get_option(['--snapshot-depfile']):
                self.depfiles = [self.rebase(self.optarg)]
            elif self.get_option([
                    '--packages', '-D', '--snapshot-kind',
                    '--depfile_output_filename'
            ]):
                pass
            elif arg in ['--deterministic', '--sound-null-safety']:
                pass
            elif arg == 'compile':
                self.extra_paths.add(
                    self.rebase(
                        os.path.join(self.dart_subdir,
                                     'snapshots/dartdev.dart.snapshot')))
                self.extra_paths.add(
                    self.rebase(os.path.join(self.dart_subdir, '../lib')))
                return self.parse_compile()
            elif arg == '../../pkg/compiler/lib/src/dart2js.dart':
                self.entry_points.add(self.rebase(arg))
                return self.parse_dart2js()
            elif arg == 'gen/utils/compiler/dart2js.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_dart2js()
            elif arg == '../../pkg/dev_compiler/bin/dartdevc.dart':
                self.entry_points.add(self.rebase(arg))
                return self.parse_dartdevc()
            elif arg == 'gen/utils/ddc/dartdevc.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_dartdevc()
            elif arg == 'gen/utils/dartanalyzer/dartanalyzer.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_dartanalyzer()
            elif arg == 'gen/utils/analysis_server/analysis_server.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_analysis_server()
            elif arg == '../../pkg/front_end/tool/_fasta/compile_platform.dart':
                self.entry_points.add(self.rebase(arg))
                return self.parse_compile_platform()
            elif arg == '../../utils/compiler/create_snapshot_entry.dart':
                self.entry_points.add(self.rebase(arg))
                self.extra_paths.add('tools/make_version.py')
                # This step is very cheap and python3 isn't in the docker image.
                self.no_remote = True
                return self.parse_create_snapshot_entry()
            elif arg == '../../utils/bazel/kernel_worker.dart':
                self.entry_points.add(self.rebase(arg))
                return self.parse_kernel_worker()
            elif arg == '../../pkg/vm/bin/gen_kernel.dart':
                self.entry_points.add(self.rebase(arg))
                return self.parse_gen_kernel()
            elif arg == 'gen/utils/kernel-service/frontend_server.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_frontend_server()
            elif arg == 'gen/utils/dtd/generate_dtd_snapshot.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_generate_dtd_snapshot()
            elif arg == 'gen/utils/dds/generate_dds_snapshot.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_generate_dds_snapshot()
            elif arg == 'gen/utils/bazel/kernel_worker.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_kernel_worker()
            elif arg == 'gen/utils/dartdev/generate_dartdev_snapshot.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_generate_dartdev_snapshot()
            elif arg == 'gen/utils/gen_kernel/bootstrap_gen_kernel.dill':
                self.extra_paths.add(self.rebase(arg))
                return self.parse_bootstrap_gen_kernel()
            elif arg == 'gen/utils/kernel-service/kernel-service_snapshot.dart.dill':
                self.extra_paths.add(self.rebase(arg))
                self.extra_paths.add(
                    self.rebase(
                        os.path.join(self.dart_subdir,
                                     'vm_platform_strong.dill')))
                return self.parse_kernel_service_snapshot()
            else:
                self.unsupported('dart', arg)

    def parse_compile(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg == 'js':
                self.extra_paths.add(
                    self.rebase(
                        os.path.join(self.dart_subdir,
                                     'snapshots/dart2js.dart.snapshot')))
                return self.parse_dart2js()
            else:
                self.unsupported('compile', arg)

    def parse_dart2js(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['-o', '--output']):
                self.outputs.append(self.rebase(self.optarg))
                self.outputs.append(
                    self.rebase(self.optarg.replace('.js', '.js.map')))
            elif self.get_option(['--platform-binaries']):
                self.extra_paths.add(
                    self.rebase(
                        os.path.join(self.optarg, 'dart2js_platform.dill')))
            elif self.get_option([
                    '--invoker', '--packages', '--libraries-spec',
                    '--snapshot-kind', '--depfile_output_filename'
            ]):
                pass
            elif arg in [
                    '--canary',
                    '--enable-asserts',
                    '-m',
                    '--minify',
                    '--no-source-maps',
            ]:
                pass
            elif not arg.startswith('-'):
                self.entry_points.add(self.rebase(arg))
            else:
                self.unsupported('dart2js', arg)

    def parse_dartdevc(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['-o', '--output']):
                self.outputs.append(self.rebase(self.optarg))
                self.outputs.append(
                    self.rebase(self.optarg.replace('.js', '.js.map')))
                self.outputs.append(
                    self.rebase(self.optarg.replace('.js', '.dill')))
            elif self.get_option(['--dart-sdk-summary']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option([
                    '--multi-root-scheme', '--multi-root-output-path',
                    '--modules'
            ]):
                pass
            elif arg in [
                    '--canary', '--no-summarize', '--sound-null-safety',
                    '--no-sound-null-safety'
            ]:
                pass
            elif not arg.startswith('-'):
                if arg.endswith('.dart'):
                    self.entry_points.add(self.rebase(arg))
                else:
                    self.extra_paths.add(self.rebase(arg))
            else:
                self.unsupported('dartdevc', arg)

    def parse_dartanalyzer(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg in ['--help']:
                pass
            else:
                self.unsupported('dartanalyzer', arg)

    def parse_analysis_server(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['--sdk']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option(['--train-using']):
                self.extra_paths.add(self.rebase(self.optarg))
                self.entry_points.add(
                    self.rebase(os.path.join(self.optarg, 'compiler_api.dart')))
                # This file isn't referenced from compiler_api.dart.
                self.entry_points.add(
                    self.rebase(
                        os.path.join(self.optarg, 'src/io/mapped_file.dart')))
            else:
                self.unsupported('analysis_server', arg)

    def parse_compile_platform(self):
        compile_platform_args = []
        single_root_scheme = None
        single_root_base = None
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['--single-root-scheme']):
                single_root_scheme = self.optarg
            elif self.get_option(['--single-root-base']):
                single_root_base = self.optarg
                # Remove trailing slash to avoid duplicate slashes later.
                if 1 < len(single_root_base) and single_root_base[-1] == '/':
                    single_root_base = single_root_base[:-1]
            elif self.get_option(['-D', '--target']):
                pass
            elif arg in [
                    '--no-defines',
                    '--nnbd-strong',
                    '--nnbd-weak',
                    '--exclude-source',
            ]:
                pass
            elif not arg.startswith('-'):
                if len(compile_platform_args) == 0:
                    pass  # e.g. dart:core
                elif len(compile_platform_args) == 1:
                    sdk = arg  # sdk via libraries.json
                    if sdk.startswith(f'{single_root_scheme}:///'):
                        sdk = sdk[len(f'{single_root_scheme}:///'):]
                        sdk = os.path.join(single_root_base, sdk)
                    if sdk.endswith('libraries.json'):
                        sdk = os.path.dirname(sdk)
                    self.extra_paths.add(self.rebase(sdk))
                elif len(compile_platform_args) == 2:  # vm_outline_strong dill
                    arg = self.rebase(arg)
                elif len(compile_platform_args) == 3:  # platform dill
                    arg = self.rebase(arg)
                    self.outputs.append(arg)
                elif len(compile_platform_args) == 4:  # outline dill
                    arg = self.rebase(arg)
                    self.outputs.append(arg)
                    if arg != compile_platform_args[2]:
                        self.extra_paths.add(compile_platform_args[2])
                else:
                    self.unsupported('compile_platform', arg)
                compile_platform_args.append(arg)
            else:
                self.unsupported('compile_platform', arg)

    def parse_create_snapshot_entry(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['--output_dir']):
                self.outputs.append(self.rebase(self.optarg))
            elif arg in ['--no-git-hash']:
                pass
            else:
                self.unsupported('create_snapshot_entry', arg)

    def parse_kernel_worker(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['-o', '--output']):
                self.outputs.append(self.rebase(self.optarg))
            elif self.get_option(['--dart-sdk-summary']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option(['--source']):
                self.entry_points.add(self.rebase(self.optarg))
            elif self.get_option(
                ['--packages-file', '--target', '--dart-sdk-summary']):
                pass
            elif arg in [
                    '--summary-only',
                    '--sound-null-safety',
                    '--no-sound-null-safety',
            ]:
                pass
            else:
                self.unsupported('kernel_worker', arg)

    def parse_gen_kernel(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['-o', '--output']):
                self.outputs.append(self.rebase(self.optarg))
            elif self.get_option(['--platform']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option([
                    '--packages', '-D', '--filesystem-root',
                    '--filesystem-scheme'
            ]):
                pass
            elif arg in ['--no-aot', '--no-embed-sources']:
                pass
            elif not arg.startswith('-'):
                self.entry_points.add(self.rebase(arg))
            else:
                self.unsupported('gen_kernel', arg)

    def parse_bootstrap_gen_kernel(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['-o', '--output']):
                self.outputs.append(self.rebase(self.optarg))
            elif self.get_option(['--platform']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option(['--packages', '-D']):
                pass
            elif arg in [
                    '--aot',
                    '--no-aot',
                    '--no-embed-sources',
                    '--no-link-platform',
                    '--enable-asserts',
            ]:
                pass
            elif self.get_option(['--depfile']):
                self.depfiles = [self.rebase(self.optarg)]
            elif not arg.startswith('-'):
                self.entry_points.add(self.rebase(arg))
            else:
                self.unsupported('bootstrap_gen_kernel', arg)

    def parse_kernel_service_snapshot(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['--train']):
                self.entry_points.add(self.rebase(self.optarg))
            else:
                self.unsupported('kernel_service_snapshot', arg)

    def parse_frontend_server(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['--platform']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option(['--sdk-root']):
                pass
            elif arg in ['--train']:
                pass
            elif not arg.startswith('-'):
                self.entry_points.add(self.rebase(arg))
            else:
                self.unsupported('frontend_server', arg)

    def parse_generate_dtd_snapshot(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg in ['--train']:
                pass
            else:
                self.unsupported('generate_dtd_snapshot', arg)

    def parse_generate_dds_snapshot(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg in ['--help']:
                pass
            else:
                self.unsupported('generate_dds_snapshot', arg)

    def parse_kernel_worker(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg in ['--help']:
                pass
            elif self.get_option(['-o', '--output']):
                self.outputs.append(self.rebase(self.optarg))
            elif self.get_option(['--packages-file']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option(['--dart-sdk-summary']):
                self.extra_paths.add(self.rebase(self.optarg))
            elif self.get_option(['--source']):
                self.entry_points.add(self.rebase(self.optarg))
            elif self.get_option(['--target']):
                pass
            elif arg in [
                    '--sound-null-safety', '--no-sound-null-safety',
                    '--summary-only'
            ]:
                pass
            else:
                self.unsupported('kernel_worker', arg)

    def parse_generate_dartdev_snapshot(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg in ['--help']:
                pass
            else:
                self.unsupported('generate_dartdev_snapshot', arg)

    def parse_gen_snapshot(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if self.get_option(['-o', '--output']):
                self.outputs.append(self.rebase(self.optarg))
            elif self.get_option([
                    '--vm_snapshot_data',
                    '--vm_snapshot_instructions',
                    '--isolate_snapshot_data',
                    '--isolate_snapshot_instructions',
                    '--elf',
            ]):
                self.outputs.append(self.rebase(self.optarg))
            elif self.get_option(['--snapshot_kind', '--snapshot-kind']):
                pass
            elif arg in [
                    '--sound-null-safety',
                    '--deterministic',
                    '--enable-asserts',
            ]:
                pass
            elif not arg.startswith('-'):
                self.extra_paths.add(self.rebase(arg))
            else:
                self.unsupported('gen_snapshot', arg)


def main(argv):
    # Like gn_run_binary, run programs relative to the build directory. The
    # command is assumed to invoke rewrapper and end its rewrapper arguments
    # with an -- argument.
    rewrapper_end = 0
    for i in range(len(argv)):
        if argv[i] == '--' and rewrapper_end == 0:
            rewrapper_end = i + 1
            if not '/' in argv[i + 1]:
                argv[i + 1] = './' + argv[i + 1]
            break

    rewrapper = Rewrapper(argv)

    if rewrapper.exec_root == None:
        raise Exception('No rewrapper --exec_root was specified')

    if not rewrapper.outputs:
        raise Exception('No output files were recognized')

    # Run the command directly if it's not supported for remote builds.
    if rewrapper.no_remote:
        run_command(argv[rewrapper_end:], 'local')
        return 0

    # Determine the set of input and output files.
    package_config = load_package_config(rewrapper.exec_root)
    if not rewrapper.depfiles:
        rewrapper.depfiles = [output + '.d' for output in rewrapper.outputs]
    output_files = rewrapper.outputs + rewrapper.depfiles
    inputs = find_inputs(rewrapper.entry_points, rewrapper.exec_root,
                         package_config)
    paths = set(
        resolve_uri(uri, rewrapper.exec_root, package_config, whole_dir=True)
        for uri in inputs)
    paths.add(os.path.join('.dart_tool', 'package_config.json'))
    for path in rewrapper.extra_paths:
        paths.add(path)
    # Ensure the working directory is included if no inputs are inside it.
    working_directory = rewrapper.rebase('.')
    if not any([path.startswith(working_directory) for path in paths]):
        paths.add(rewrapper.rebase('build.ninja.stamp'))
    paths = list(paths)
    paths.sort()

    # Construct the final rewrapped command line.
    command = [argv[1]]
    command.append('--labels=type=tool')
    command.append('--inputs=' + ','.join(paths))
    command.append('--output_files=' + ','.join(output_files))
    # Absolute paths must not be used with RBE, but since the build currently
    # heavily relies on them, work around this issue by rewriting the command
    # to instead use relative paths. The Dart SDK build rules needs to be fixed
    # rather than doing this, but this is an initial step towards that goal
    # which will land in subsequent follow up changes.
    command += argv[2:rewrapper_end] + [
        rewrite_absolute(arg, rewrapper.exec_root, working_directory)
        for arg in argv[rewrapper_end:]
    ]

    # Finally execute the command remotely.
    run_command(command, rewrapper.exec_strategy)

    # Until the depfiles are fixed so they don't contain absoiute paths, we need
    # to rewrite the absoute paths appropriately.
    for depfile in rewrapper.depfiles:
        lines = []
        try:
            with open(os.path.join(rewrapper.exec_root, depfile), 'r') as file:
                lines = file.readlines()
            lines = [
                line.replace('/b/f/w', rewrapper.exec_root) for line in lines
            ]
            with open(os.path.join(rewrapper.exec_root, depfile), 'w') as file:
                file.writelines(lines)
        except FileNotFoundError:
            pass

    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))
