// Copyright (c) 2018, 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:http_multi_server/http_multi_server.dart';
import 'package:build_runner_core/build_runner_core.dart';
import 'package:io/io.dart';
import 'package:logging/logging.dart';
import 'package:shelf/shelf_io.dart';

import '../generate/build.dart';
import '../logging/std_io_logging.dart';
import '../server/server.dart';
import 'options.dart';
import 'watch.dart';

/// Extends [WatchCommand] with dev server functionality.
class ServeCommand extends WatchCommand {
  ServeCommand() {
    argParser
      ..addOption(hostnameOption,
          help: 'Specify the hostname to serve on', defaultsTo: 'localhost')
      ..addFlag(logRequestsOption,
          defaultsTo: false,
          negatable: false,
          help: 'Enables logging for each request to the server.')
      ..addFlag(liveReloadOption,
          defaultsTo: false,
          negatable: false,
          help: 'Enables automatic page reloading on rebuilds. '
              "Can't be used together with --$hotReloadOption.")
      ..addFlag(hotReloadOption,
          defaultsTo: false,
          negatable: false,
          help: 'Enables automatic reloading of changed modules on rebuilds. '
              "Can't be used together with --$liveReloadOption.");
  }

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

  @override
  String get name => 'serve';

  @override
  String get description =>
      'Runs a development server that serves the specified targets and runs '
      'builds based on file system updates.';

  @override
  ServeOptions readOptions() => ServeOptions.fromParsedArgs(
      argResults, argResults.rest, packageGraph.root.name, this);

  @override
  Future<int> run() async {
    final servers = <ServeTarget, HttpServer>{};
    return _runServe(servers).whenComplete(() async {
      await Future.wait(
          servers.values.map((server) => server.close(force: true)));
    });
  }

  Future<int> _runServe(Map<ServeTarget, HttpServer> servers) async {
    var options = readOptions();
    try {
      await Future.wait(options.serveTargets.map((target) async {
        servers[target] =
            await HttpMultiServer.bind(options.hostName, target.port);
      }));
    } on SocketException catch (e) {
      var listener = Logger.root.onRecord.listen(stdIOLogListener());
      if (e.address != null && e.port != null) {
        logger.severe(
            'Error starting server at ${e.address.address}:${e.port}, address '
            'is already in use. Please kill the server running on that port or '
            'serve on a different port and restart this process.');
      } else {
        logger.severe('Error starting server on ${options.hostName}.');
      }
      await listener.cancel();
      return ExitCode.osError.code;
    }

    var handler = await watch(
      builderApplications,
      deleteFilesByDefault: options.deleteFilesByDefault,
      enableLowResourcesMode: options.enableLowResourcesMode,
      configKey: options.configKey,
      buildDirs: options.buildDirs,
      outputSymlinksOnly: options.outputSymlinksOnly,
      packageGraph: packageGraph,
      trackPerformance: options.trackPerformance,
      skipBuildScriptCheck: options.skipBuildScriptCheck,
      verbose: options.verbose,
      builderConfigOverrides: options.builderConfigOverrides,
      isReleaseBuild: options.isReleaseBuild,
      logPerformanceDir: options.logPerformanceDir,
      directoryWatcherFactory: options.directoryWatcherFactory,
      buildFilters: options.buildFilters,
    );

    if (handler == null) return ExitCode.config.code;

    servers.forEach((target, server) {
      serveRequests(
          server,
          handler.handlerFor(target.dir,
              logRequests: options.logRequests,
              buildUpdates: options.buildUpdates));
    });

    _ensureBuildWebCompilersDependency(packageGraph, logger);

    final completer = Completer<int>();
    handleBuildResultsStream(handler.buildResults, completer);
    _logServerPorts(handler, options, logger);
    return completer.future;
  }

  void _logServerPorts(
      ServeHandler serveHandler, ServeOptions options, Logger logger) async {
    await serveHandler.currentBuild;
    // Warn if in serve mode with no servers.
    if (options.serveTargets.isEmpty) {
      logger.warning(
          'Found no known web directories to serve, but running in `serve` '
          'mode. You may expliclity provide a directory to serve with trailing '
          'args in <dir>[:<port>] format.');
    } else {
      for (var target in options.serveTargets) {
        stdout.writeln('Serving `${target.dir}` on '
            'http://${options.hostName}:${target.port}');
      }
    }
  }
}

void _ensureBuildWebCompilersDependency(PackageGraph packageGraph, Logger log) {
  if (!packageGraph.allPackages.containsKey('build_web_compilers')) {
    log.warning('''
    Missing dev dependency on package:build_web_compilers, which is required to serve Dart compiled to JavaScript.

    Please update your dev_dependencies section of your pubspec.yaml:

    dev_dependencies:
      build_runner: any
      build_test: any
      build_web_compilers: any''');
  }
}
