// Copyright (c) 2019, 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 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:logging/logging.dart';

import '../logging.dart';
import '../pubspec.dart';
import '../serve/dev_workflow.dart';
import 'configuration.dart';
import 'shared.dart';

/// Command to run a server for local web development with the build daemon.
class ServeCommand extends Command<int> {
  @override
  final name = 'serve';

  @override
  final description = 'Run a local web development server and a file system'
      ' watcher that rebuilds on changes.';

  @override
  final argParser = ArgParser(usageLineLength: lineLength)
    ..addOption(autoOption, help: '''
Automatically performs an action after each build:

restart: Reload modules and re-invoke main (loses current state)
refresh: Performs a full page refresh.
''', allowed: ['restart', 'refresh'])
    ..addFlag(debugFlag,
        help: 'Enable the launching of DevTools (Alt + D / Option + D). '
            'This also enables --$launchInChromeFlag.')
    ..addFlag(debugExtensionFlag,
        help: 'Enable the backend for the Dart Debug Extension.')
    ..addFlag(enableInjectedClientFlag,
        help: 'Whether or not to inject the client.js script in web apps. This '
            'is required for all debugging related features, but may interact '
            'poorly with proxy servers or other environments.',
        defaultsTo: true)
    ..addSeparator('Advanced:')
    ..addOption(chromeDebugPortFlag,
        help: 'Specify which port the Chrome debugger is listening on. '
            'If used with $launchInChromeFlag Chrome will be started with the'
            ' debugger listening on this port.')
    ..addOption(hostnameFlag,
        help: 'Specify the hostname to serve on.', defaultsTo: 'localhost')
    ..addFlag(hotRestartFlag,
        negatable: false,
        help: 'Automatically reloads changed modules after each build '
            'and restarts your application.\n'
            "Can't be used with $liveReloadFlag.",
        hide: true)
    ..addFlag(hotReloadFlag, negatable: false, hide: true)
    ..addFlag(launchInChromeFlag,
        help: 'Automatically launches your application in Chrome with the '
            'debug port open. Use $chromeDebugPortFlag to specify a specific '
            'port to attach to an already running chrome instance instead.')
    ..addOption(userDataDirFlag,
        defaultsTo: null,
        help: 'Use with $launchInChromeFlag to specify user data directory '
            'to pass to chrome. Will start chrome window logged into default '
            'profile with enabled extensions. Use `auto` as a value to infer '
            'the default directory for the current OS. '
            'Note: only supported for Mac OS X and linux platforms.')
    ..addFlag(liveReloadFlag,
        negatable: false,
        help: 'Automatically refreshes the page after each successful build.\n'
            "Can't be used with $hotRestartFlag.",
        hide: true)
    ..addFlag(logRequestsFlag,
        negatable: false,
        help: 'Enables logging for each request to the server.')
    ..addOption(tlsCertChainFlag,
        help:
            'The file location to a TLS Certificate to create an HTTPs server.\n'
            'Must be used with $tlsCertKeyFlag.')
    ..addOption(tlsCertKeyFlag,
        help: 'The file location to a TLS Key to create an HTTPs server.\n'
            'Must be used with $tlsCertChainFlag.')
    ..addSeparator('Common:');

  ServeCommand() {
    addSharedArgs(argParser, releaseDefault: false);
  }

  @override
  String get invocation => '${super.invocation} [<directory>[:<port>]]...';

  @override
  Future<int> run() async {
    Configuration configuration;
    configuration = Configuration.fromArgs(argResults);
    configureLogWriter(configuration.verbose);
    PubspecLock? pubspecLock;
    try {
      pubspecLock = await readPubspecLock(configuration);
    } on PackageException catch (e) {
      logWriter(Level.SEVERE, 'Pubspec errors: ', error: '${e.details}');
      rethrow;
    }
    // Forward remaining arguments as Build Options to the Daemon.
    // This isn't documented. Should it be advertised?
    var buildOptions = buildRunnerArgs(pubspecLock, configuration)
      ..addAll(argResults!.rest.where((arg) => arg.startsWith('-')).toList());
    var extraArgs = argResults?.rest ?? [];
    var directoryArgs = extraArgs.where((arg) => !arg.startsWith('-')).toList();
    var targetPorts = parseDirectoryArgs(directoryArgs);
    validateLaunchApps(configuration.launchApps, targetPorts.keys);

    var workflow =
        await DevWorkflow.start(configuration, buildOptions, targetPorts);
    await workflow.done;
    return 0;
  }
}
