#!/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', 'final']:
            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('/dartvm'):
                self.dart_subdir = os.path.dirname(arg)
                return self.parse_dart()
            elif arg.endswith('/dartaotruntime'):
                self.dart_subdir = os.path.dirname(arg)
                return self.parse_dartaotruntime()
            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):
        self.extra_paths.add(
            self.rebase(os.path.join(self.dart_subdir, 'dartvm')))
        self.extra_paths.add(
            self.rebase(
                os.path.join(self.dart_subdir,
                             'snapshots/kernel-service.dart.snapshot')))

        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', '--coverage',
                    '--ignore-unrecognized-flags'
            ]):
                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/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.dill')))
                return self.parse_kernel_service_snapshot()
            else:
                self.unsupported('dart', arg)

    def parse_dartaotruntime(self):
        while self.has_next_arg:
            arg = self.next_arg()
            if arg.endswith('/dart2js_aot.dart.snapshot'):
                self.extra_paths.add(
                    self.rebase(
                        os.path.join(self.dart_subdir,
                                     'snapshots/dart2js_aot.dart.snapshot')))
                return self.parse_dart2js()
            else:
                self.unsupported('dartaotruntime', 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,
                                             'dartaotruntime')))
                self.extra_paths.add(
                    self.rebase(
                        os.path.join(self.dart_subdir,
                                     'snapshots/dart2js_aot.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',
                    '--coverage', '--ignore-unrecognized-flags'
            ]):
                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(['--packages']):
                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')))
                # These files aren't referenced from compiler_api.dart.
                self.entry_points.add(
                    self.rebase(
                        os.path.join(self.optarg, 'src/io/mapped_file.dart')))
                self.entry_points.add(
                    self.rebase(
                        'package:shell_arg_splitter/shell_arg_splitter.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 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(['--dynamic-interface']):
                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',
                    '--link-platform',
            ]:
                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', '--coverage',
                    '--ignore-unrecognized-flags'
            ]):
                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))
