#!/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):
        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')))
                # 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 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))
