// Copyright (c) 2022, 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.

import 'dart:async';
import 'dart:io';

import 'package:args/args.dart';
import 'package:browser_launcher/browser_launcher.dart';
import 'package:devtools_shared/devtools_extensions_io.dart';
import 'package:devtools_shared/devtools_shared.dart';
import 'package:http_multi_server/http_multi_server.dart';
import 'package:path/path.dart' as path;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf;

import 'src/devtools/client.dart';
import 'src/devtools/dtd.dart';
import 'src/devtools/handler.dart';
import 'src/devtools/machine_mode_command_handler.dart';
import 'src/devtools/memory_profile.dart';
import 'src/devtools/utils.dart';
import 'src/utils/console.dart';

class DevToolsServer {
  static const protocolVersion = '1.2.0';
  static const defaultTryPorts = 10;
  static const defaultDdsHost = '127.0.0.1';
  static const defaultDdsPort = 0;
  static const commandDescription =
      'Open DevTools (optionally connecting to an existing application).';

  static const argHelp = 'help';
  static const argVmUri = 'vm-uri';
  static const argEnableNotifications = 'enable-notifications';
  static const argAllowEmbedding = 'allow-embedding';
  static const argAppSizeBase = 'app-size-base';
  static const argAppSizeTest = 'app-size-test';
  static const argHeadlessMode = 'headless';
  static const argDdsHost = 'dds-host';
  static const argDdsPort = 'dds-port';
  static const argDebugMode = 'debug';
  static const argDisableCors = 'disable-cors';
  static const argDtdUri = 'dtd-uri';
  static const argDtdExposedUri = 'dtd-exposed-uri';
  static const argPrintDtd = 'print-dtd';
  static const argLaunchBrowser = 'launch-browser';
  static const argMachine = 'machine';
  static const argHost = 'host';
  static const argPort = 'port';
  static const argProfileMemory = 'record-memory-profile';
  static const argTryPorts = 'try-ports';
  static const argVerbose = 'verbose';
  static const argVersion = 'version';
  static const argDisableServiceOriginCheck = 'disable-service-origin-check';
  static const launchDevToolsService = 'launchDevTools';

  MachineModeCommandHandler? _machineModeCommandHandler;
  late ClientManager clientManager;
  final bool _isChromeOS = File('/dev/.cros_milestone').existsSync();

  /// Builds an arg parser for the DevTools server.
  ///
  /// [includeHelpOption] should be set to false if this arg parser will be used
  /// in a Command subclass.
  static ArgParser buildArgParser({
    bool verbose = false,
    bool includeHelpOption = true,
    int? usageLineLength,
  }) {
    final argParser = ArgParser(
      usageLineLength: usageLineLength,
    );

    if (includeHelpOption) {
      argParser.addFlag(
        argHelp,
        negatable: false,
        abbr: 'h',
        help: 'Prints help output.',
      );
    }
    argParser
      ..addFlag(
        argVersion,
        negatable: false,
        help: 'Prints the DevTools version.',
      )
      ..addFlag(
        argVerbose,
        negatable: false,
        abbr: 'v',
        help: 'Output more informational messages.',
      )
      ..addOption(
        argHost,
        valueHelp: 'host',
        help: 'Hostname to serve DevTools on (defaults to localhost).',
      )
      ..addOption(
        argPort,
        defaultsTo: '9100',
        valueHelp: 'port',
        help: 'Port to serve DevTools on; specify 0 to automatically use any '
            'available port.',
      )
      ..addOption(
        argDtdUri,
        valueHelp: 'uri',
        help: 'A URI pointing to a Dart Tooling Daemon that DevTools should '
            'interface with.',
      )
      ..addOption(
        argDtdExposedUri,
        valueHelp: 'uri',
        help: 'An optional URI for the DartTooling Daemon (--dtd-uri) that has '
            'been exposed to the front-end to support environments split across '
            'machines such as a web-based editor.',
      )
      ..addFlag(
        argLaunchBrowser,
        help:
            'Launches DevTools in a browser immediately at start.\n(defaults to on unless in --machine mode)',
      )
      ..addFlag(
        argMachine,
        negatable: false,
        help: 'Sets output format to JSON for consumption in tools.',
      )
      ..addFlag(
        argDisableServiceOriginCheck,
        negatable: false,
        help: 'Disables the requirements for Host and Origin header validation '
            'for DevTools server connections. Host and Origin validation helps '
            'protect against DNS-rebinding and CSRF attacks, so it is not '
            'recommended to disable them.',
      )
      ..addSeparator('Memory profiling options:')
      ..addOption(
        argProfileMemory,
        valueHelp: 'file',
        defaultsTo: 'memory_samples.json',
        help:
            'Start devtools headlessly and write memory profiling samples to the '
            'indicated file.',
      );

    argParser.addSeparator('App size options:');

    argParser
      ..addOption(
        argAppSizeBase,
        aliases: ['appSizeBase'],
        valueHelp: 'file',
        help: 'Path to the base app size file used for app size debugging.',
      )
      ..addOption(
        argAppSizeTest,
        aliases: ['appSizeTest'],
        valueHelp: 'file',
        help:
            'Path to the test app size file used for app size debugging.\nThis '
            'file should only be specified if --$argAppSizeBase is also '
            'specified.',
        hide: !verbose,
      );

    if (verbose) {
      argParser.addSeparator('Advanced options:');
    }

    // Args to show for verbose mode.
    argParser
      ..addOption(
        argTryPorts,
        defaultsTo: DevToolsServer.defaultTryPorts.toString(),
        valueHelp: 'count',
        help: 'The number of ascending ports to try binding to before failing '
            'with an error.',
        hide: !verbose,
      )
      ..addOption(
        argDdsHost,
        defaultsTo: DevToolsServer.defaultDdsHost,
        valueHelp: 'bind-address',
        help:
            "The address the Dart Development Service (DDS) should attempt to "
            "bind to if a DDS instance isn't active and a VM service URI is "
            "provided.",
        hide: !verbose,
      )
      ..addOption(
        argDdsPort,
        defaultsTo: DevToolsServer.defaultDdsPort.toString(),
        valueHelp: 'port',
        help:
            "The address the Dart Development Service (DDS) should attempt to "
            "bind to if a DDS instance isn't active and a VM service URI is "
            "provided.",
        hide: !verbose,
      )
      ..addFlag(
        argEnableNotifications,
        negatable: false,
        help: 'Requests notification permissions immediately when a client '
            'connects back to the server.',
        hide: !verbose,
      )
      ..addFlag(
        argAllowEmbedding,
        help: 'Allow embedding DevTools inside an iframe.',
        hide: !verbose,
      )
      ..addFlag(
        argDisableCors,
        help:
            'Disable CORS so that the DevTools server can communicate with the '
            'DevTools front end served on a different origin. Use caution when '
            'passing this flag since allowing access to the DevTools server '
            'from other origins may have security implications.',
        defaultsTo: false,
        hide: verbose,
      )
      ..addFlag(
        argHeadlessMode,
        negatable: false,
        help: 'Causes the server to spawn Chrome in headless mode for use in '
            'automated testing.',
        hide: !verbose,
      )
      ..addFlag(
        argPrintDtd,
        negatable: false,
        help: 'Print the address of the Dart Tooling Daemon, if one is hosted '
            'by the DevTools server.',
        hide: !verbose,
      );

    // Deprecated and hidden args.
    // TODO: Remove this - prefer that clients use the rest arg.
    argParser
      ..addOption(
        argVmUri,
        defaultsTo: '',
        help: 'VM Service protocol URI.',
        hide: true,
      )

      // Development only args.
      ..addFlag(
        argDebugMode,
        negatable: false,
        help: 'Run a debug build of the DevTools web frontend.',
        hide: true,
      );

    return argParser;
  }

  /// Serves DevTools.
  ///
  /// `handler` is the [shelf.Handler] that the server will use for all requests.
  /// If null, [defaultHandler] will be used. Defaults to null.
  ///
  /// `customDevToolsPath` is a path to a directory containing a pre-built
  /// DevTools application.
  ///
  // Note: this method is used by the Dart CLI and by package:dwds.
  Future<HttpServer?> serveDevTools({
    bool enableStdinCommands = true,
    bool machineMode = false,
    bool debugMode = false,
    bool launchBrowser = false,
    bool enableNotifications = false,
    bool allowEmbedding = true,
    bool disableCors = false,
    bool headlessMode = false,
    bool verboseMode = false,
    bool printDtdUri = false,
    String? hostname,
    String? customDevToolsPath,
    int port = 0,
    int numPortsToTry = defaultTryPorts,
    shelf.Handler? handler,
    String? serviceProtocolUri,
    String? profileFilename,
    String? appSizeBase,
    String? appSizeTest,
    DtdInfo? dtdInfo,
    bool disableServiceOriginCheck = false,
  }) async {
    hostname ??= 'localhost';

    // Collect profiling information.
    if (profileFilename != null && serviceProtocolUri != null) {
      final Uri? vmServiceUri = Uri.tryParse(serviceProtocolUri);
      if (vmServiceUri != null) {
        await _hookupMemoryProfiling(
          vmServiceUri,
          profileFilename,
          verboseMode,
        );
      }
      return null;
    }

    if (machineMode) {
      assert(
        enableStdinCommands,
        'machineMode only works with enableStdinCommands.',
      );
    }

    clientManager = ClientManager(
      requestNotificationPermissions: enableNotifications,
    );

    dtdInfo ??= await startDtd(
      machineMode: machineMode,
      printDtdUri: printDtdUri,
    );

    HttpServer? server;
    SocketException? ex;
    while (server == null && numPortsToTry >= 0) {
      // If we have tried [numPortsToTry] ports and still have not been able to
      // connect, try port 0 to find a random available port.
      if (numPortsToTry == 0) port = 0;

      try {
        server = await HttpMultiServer.bind(hostname, port);
      } on SocketException catch (e) {
        ex = e;
        numPortsToTry--;
        port++;
      }
    }

    // Re-throw the last exception if we failed to bind.
    if (server == null && ex != null) {
      throw ex;
    }

    // Type promote server.
    server!;

    final serverUri = Uri(
      scheme: 'http',
      host: hostname,
      port: server.port,
    );

    handler ??= await defaultHandler(
      buildDir: customDevToolsPath,
      clientManager: clientManager,
      dtd: dtdInfo,
      devtoolsExtensionsManager: ExtensionsManager(),
      disableServiceOriginCheck: disableServiceOriginCheck,
      serverUri: serverUri,
    );

    if (allowEmbedding) {
      server.defaultResponseHeaders.remove('x-frame-options', 'SAMEORIGIN');
      // The origin-agent-cluster header is required to support the embedding of
      // Dart DevTools in Chrome DevTools.
      server.defaultResponseHeaders.add('origin-agent-cluster', '?1');
    }

    // CORS restrictions may be disabled for the purposes of debugging or
    // testing when it is useful to allow connecting a debug instance of
    // DevTools app to a running DevTools server.
    if (disableCors) {
      server.defaultResponseHeaders.add(
        HttpHeaders.accessControlAllowOriginHeader,
        '*',
      );
    }

    // Ensure browsers don't cache older versions of the app.
    server.defaultResponseHeaders.add(
      HttpHeaders.cacheControlHeader,
      'no-store',
    );

    // Add the headers required to serve with wasm.
    server.defaultResponseHeaders
      ..add('Cross-Origin-Embedder-Policy', 'credentialless')
      ..add('Cross-Origin-Opener-Policy', 'same-origin')
      ..add('Cross-Origin-Resource-Policy', 'cross-origin');

    // Serve requests in an error zone to prevent failures
    // when running from another error zone.
    runZonedGuarded(
      () => shelf.serveRequests(server!, handler!),
      (e, _) => print('Error serving requests: $e'),
    );

    final devToolsUrl = 'http://${server.address.host}:${server.port}';

    if (launchBrowser) {
      if (serviceProtocolUri != null) {
        serviceProtocolUri =
            normalizeVmServiceUri(serviceProtocolUri).toString();
      }

      final queryParameters = {
        if (serviceProtocolUri != null) 'uri': serviceProtocolUri,
        if (appSizeBase != null) 'appSizeBase': appSizeBase,
        if (appSizeTest != null) 'appSizeTest': appSizeTest,
      };
      String url = Uri.parse(devToolsUrl)
          .replace(queryParameters: queryParameters)
          .toString();

      // If app size parameters are present, open to the standalone `app-size`
      // page, regardless if there is a vm service uri specified. We only check
      // for the presence of [appSizeBase] here because [appSizeTest] may or may
      // not be specified (it should only be present for diffs). If [appSizeTest]
      // is present without [appSizeBase], we will ignore the parameter.
      if (appSizeBase != null) {
        final startQueryParamIndex = url.indexOf('?');
        if (startQueryParamIndex != -1) {
          url = '${url.substring(0, startQueryParamIndex)}'
              '/#/app-size'
              '${url.substring(startQueryParamIndex)}';
        }
      }

      try {
        await Chrome.start([url]);
      } catch (e) {
        print('Unable to launch Chrome: $e\n');
      }
    }

    if (enableStdinCommands) {
      String message = '''Serving DevTools at $devToolsUrl.

          Hit ctrl-c to terminate the server.''';
      if (!machineMode && debugMode) {
        // Add bold to help find the correct url to open.
        message = ConsoleUtils.bold('$message\n');
      }

      DevToolsUtils.printOutput(
        message,
        {
          'event': 'server.started',
          // TODO(dantup): Remove this `method` field when we're sure VS Code
          // users are all on a newer version that uses `event`. We incorrectly
          // used `method` for the original releases.
          'method': 'server.started',
          'params': {
            'host': server.address.host,
            'port': server.port,
            'pid': pid,
            'protocolVersion': protocolVersion,
          }
        },
        machineMode: machineMode,
      );

      if (machineMode) {
        _machineModeCommandHandler = MachineModeCommandHandler(server: this);
        await _machineModeCommandHandler!.initialize(
          devToolsUrl: devToolsUrl,
          headlessMode: headlessMode,
        );
      }
    }

    return server;
  }

  void _printUsage(ArgParser argParser) {
    print(commandDescription);
    print('\nUsage: devtools [arguments] [service protocol uri]');
    print(argParser.usage);
  }

  /// Wraps [serveDevTools] `arguments` parsed, as from the command line.
  ///
  /// For more information on `handler`, see [serveDevTools].
  // Note: this method is used in google3 as well as by DevTools' main method.
  Future<HttpServer?> serveDevToolsWithArgs(
    List<String> arguments, {
    shelf.Handler? handler,
    String? customDevToolsPath,
  }) async {
    ArgResults args;
    final verbose = arguments.contains('-v') || arguments.contains('--verbose');
    final argParser = buildArgParser(verbose: verbose);
    try {
      args = argParser.parse(arguments);
    } on FormatException catch (e) {
      print(e.message);
      print('');
      _printUsage(argParser);
      return null;
    }

    return await _serveDevToolsWithArgs(
      args,
      verbose,
      handler: handler,
      customDevToolsPath: customDevToolsPath,
    );
  }

  Future<HttpServer?> _serveDevToolsWithArgs(
    ArgResults args,
    bool verbose, {
    shelf.Handler? handler,
    String? customDevToolsPath,
  }) async {
    final help = args[argHelp];
    final bool version = args[argVersion];
    final bool machineMode = args[argMachine];
    // launchBrowser defaults based on machine-mode if not explicitly supplied.
    final bool launchBrowser = args.wasParsed(argLaunchBrowser)
        ? args[argLaunchBrowser]
        : !machineMode;
    final bool enableNotifications = args[argEnableNotifications];
    final bool allowEmbedding =
        args.wasParsed(argAllowEmbedding) ? args[argAllowEmbedding] : true;
    final bool disableCors =
        args.wasParsed(argDisableCors) ? args[argDisableCors] : false;
    final bool disableServiceOriginCheck =
        args.wasParsed(argDisableServiceOriginCheck)
            ? args[argDisableServiceOriginCheck]
            : false;

    final port = args[argPort] != null ? int.tryParse(args[argPort]) ?? 0 : 0;

    final bool headlessMode = args[argHeadlessMode];
    final bool debugMode = args[argDebugMode];

    final numPortsToTry = args[argTryPorts] != null
        ? int.tryParse(args[argTryPorts]) ?? 0
        : defaultTryPorts;

    final bool verboseMode = args[argVerbose];
    final String? hostname = args[argHost];

    // A helper to print a message and usage information that can be used in
    // a return statement.
    Null printUsage(String message) {
      print(message);
      print('');
      _printUsage(buildArgParser(verbose: verbose));
    }

    Uri? dtdUri;
    if (args.wasParsed(argDtdUri)) {
      dtdUri = Uri.tryParse(args[argDtdUri]);
      if (dtdUri == null || !dtdUri.hasScheme) {
        return printUsage('--dtd-uri must be a valid URI');
      }
    }

    Uri? dtdExposedUri;
    if (args.wasParsed(argDtdExposedUri)) {
      if (dtdUri == null) {
        return printUsage(
            '--dtd-exposed-uri can only be supplied with --dtd-uri');
      }

      dtdExposedUri = Uri.tryParse(args[argDtdExposedUri]);
      if (dtdExposedUri == null || !dtdExposedUri.hasScheme) {
        return printUsage('--dtd-exposed-uri must be a valid URI');
      }
    }

    final printDtdUri = args.wasParsed(argPrintDtd);

    if (help) {
      return printUsage(
          'Dart DevTools version ${await DevToolsUtils.getVersion(customDevToolsPath ?? "")}');
    }

    if (version) {
      final versionStr =
          await DevToolsUtils.getVersion(customDevToolsPath ?? '');
      DevToolsUtils.printOutput(
        'Dart DevTools version $versionStr',
        {
          'version': versionStr,
        },
        machineMode: machineMode,
      );
      return null;
    }

    // Prefer getting the VM URI from the rest args; fall back on the 'vm-url'
    // option otherwise.
    String? serviceProtocolUri;
    if (args.rest.isNotEmpty) {
      serviceProtocolUri = args.rest.first;
    } else if (args.wasParsed(argVmUri)) {
      serviceProtocolUri = args[argVmUri];
    }

    // Support collecting profile data.
    String? profileFilename;
    if (args.wasParsed(argProfileMemory)) {
      profileFilename = args[argProfileMemory];
    }
    if (profileFilename != null && !path.isAbsolute(profileFilename)) {
      profileFilename = path.absolute(profileFilename);
    }

    // App size info.
    String? appSizeBase = args[argAppSizeBase];
    if (appSizeBase != null && !path.isAbsolute(appSizeBase)) {
      appSizeBase = path.absolute(appSizeBase);
    }
    String? appSizeTest = args[argAppSizeTest];
    if (appSizeTest != null && !path.isAbsolute(appSizeTest)) {
      appSizeTest = path.absolute(appSizeTest);
    }

    return serveDevTools(
      machineMode: machineMode,
      debugMode: debugMode,
      launchBrowser: launchBrowser,
      enableNotifications: enableNotifications,
      allowEmbedding: allowEmbedding,
      disableCors: disableCors,
      port: port,
      headlessMode: headlessMode,
      numPortsToTry: numPortsToTry,
      handler: handler,
      customDevToolsPath: customDevToolsPath,
      serviceProtocolUri: serviceProtocolUri,
      profileFilename: profileFilename,
      verboseMode: verboseMode,
      hostname: hostname,
      appSizeBase: appSizeBase,
      appSizeTest: appSizeTest,
      dtdInfo:
          dtdUri != null ? DtdInfo(dtdUri, exposedUri: dtdExposedUri) : null,
      printDtdUri: printDtdUri,
      disableServiceOriginCheck: disableServiceOriginCheck,
    );
  }

  Future<Map<String, dynamic>> launchDevTools(
    Map<String, dynamic> params,
    Uri vmServiceUri,
    String devToolsUrl,
    bool headlessMode,
    bool machineMode,
  ) async {
    // First see if we have an existing DevTools client open that we can
    // reuse.
    final canReuse =
        params.containsKey('reuseWindows') && params['reuseWindows'] == true;
    final shouldNotify =
        params.containsKey('notify') && params['notify'] == true;
    final page = params['page'];
    if (canReuse &&
        await _tryReuseExistingDevToolsInstance(
          vmServiceUri,
          page,
          shouldNotify,
        )) {
      _emitLaunchEvent(
        reused: true,
        notified: shouldNotify,
        pid: null,
        machineMode: machineMode,
      );
      return {
        'reused': true,
        'notified': shouldNotify,
      };
    }

    final uriParams = <String, dynamic>{};

    // Copy over queryParams passed by the client
    params['queryParams']?.forEach((key, value) => uriParams[key] = value);

    // Add the URI to the VM service
    uriParams['uri'] = vmServiceUri.toString();

    final devToolsUri = Uri.parse(devToolsUrl);
    final uriToLaunch = buildUriToLaunch(
      devToolsUri,
      page,
      uriParams,
    );

    // TODO(dantup): When ChromeOS has support for tunneling all ports we can
    // change this to always use the native browser for ChromeOS and may wish to
    // handle this inside `browser_launcher`; https://crbug.com/848063.
    final useNativeBrowser = _isChromeOS &&
        _isAccessibleToChromeOSNativeBrowser(devToolsUri) &&
        _isAccessibleToChromeOSNativeBrowser(vmServiceUri);
    int? browserPid;
    if (useNativeBrowser) {
      await Process.start('x-www-browser', [uriToLaunch.toString()]);
    } else {
      final args = headlessMode
          ? [
              '--headless',
              // When running headless, Chrome will quit immediately after
              // loading the page unless we have the debug port open.
              '--remote-debugging-port=9223',
              '--disable-gpu',
              '--no-sandbox',
              // When running on MacOS, Chrome may open system dialogs
              // requesting credentials. This uses a mock keychain to avoid that
              // dialog from blocking.
              '--use-mock-keychain',
            ]
          : <String>[];
      final proc = await Chrome.start([uriToLaunch.toString()], args: args);
      browserPid = proc.pid;
    }
    _emitLaunchEvent(
        reused: false,
        notified: false,
        pid: browserPid!,
        machineMode: machineMode);
    return {
      'reused': false,
      'notified': false,
      'pid': browserPid,
    };
  }

  Future<void> _hookupMemoryProfiling(
    Uri observatoryUri,
    String profileFile, [
    bool verboseMode = false,
  ]) async {
    final service = await DevToolsUtils.connectToVmService(observatoryUri);
    if (service == null) {
      return;
    }

    final memoryProfiler = MemoryProfile(service, profileFile, verboseMode);
    memoryProfiler.startPolling();

    print('Writing memory profile samples to $profileFile...');
  }

  /// Tries to reuse an existing DevTools instance.
  ///
  /// Because SSE connections have timeouts that prevent us knowing if a client
  /// has really gone away for up to 30s, this method will attempt to ping
  /// candidate first to see if it is still responsive.
  Future<bool> _tryReuseExistingDevToolsInstance(
    Uri vmServiceUri,
    String? page,
    bool notifyUser,
  ) async {
    // First try to find a client that's already connected to this VM service,
    // and just send the user a notification for that one.
    final existingClient =
        await clientManager.findExistingConnectedReusableClient(vmServiceUri);
    if (existingClient != null) {
      try {
        if (page != null) {
          existingClient.showPage(page);
        }
        if (notifyUser) {
          existingClient.notify();
        }
        return true;
      } catch (e) {
        print('Failed to reuse existing connected DevTools client');
        print(e);
      }
    }

    final reusableClient = await clientManager.findReusableClient();
    if (reusableClient != null) {
      try {
        reusableClient.connectToVmService(vmServiceUri, notifyUser);
        return true;
      } catch (e) {
        print('Failed to reuse existing DevTools client');
        print(e);
      }
    }
    return false;
  }

  static String buildUriToLaunch(
    Uri devToolsUri,
    String? page,
    Map<String, dynamic>? params,
  ) {
    page ??= '';
    var pathSep = devToolsUri.path.endsWith('/') ? '' : '/';
    var newPath = '${devToolsUri.path}$pathSep$page';
    var newParams = {
      ...devToolsUri.queryParameters,
      ...?params,
    };
    return devToolsUri
        .replace(
            path: newPath,
            queryParameters: newParams.isNotEmpty ? newParams : null)
        .toString();
  }

  /// Prints a launch event to stdout so consumers of the DevTools server
  /// can see when clients are being launched/reused.
  void _emitLaunchEvent(
      {required bool reused,
      required bool notified,
      required int? pid,
      required bool machineMode}) {
    DevToolsUtils.printOutput(
      null,
      {
        'event': 'client.launch',
        'params': {
          'reused': reused,
          'notified': notified,
          'pid': pid,
        },
      },
      machineMode: machineMode,
    );
  }

  bool _isAccessibleToChromeOSNativeBrowser(Uri uri) {
    const tunneledPorts = {
      8000,
      8008,
      8080,
      8085,
      8888,
      9005,
      3000,
      4200,
      5000
    };
    return uri.hasPort && tunneledPorts.contains(uri.port);
  }
}
