// 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 'dart:convert';
import 'dart:io';

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:async/async.dart';
import 'package:logging/logging.dart';

import '../daemon/app_domain.dart';
import '../daemon/daemon.dart';
import '../daemon/daemon_domain.dart';
import '../logging.dart';
import '../serve/dev_workflow.dart';
import '../serve/utils.dart';
import 'configuration.dart';
import 'shared.dart';

Stream<Map<String, dynamic>> get _stdinCommandStream => stdin
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .where((String line) => line.startsWith('[{') && line.endsWith('}]'))
        .map<Map<String, dynamic>>((String line) {
      line = line.substring(1, line.length - 1);
      return json.decode(line) as Map<String, dynamic>;
    });

void _stdoutCommandResponse(Map<String, dynamic> command) {
  stdout.writeln('[${json.encode(command)}]');
}

/// A mode for running WebDev from command-line tools.
///
/// Communication happens over STDIO using JSON-RPC.
///
/// This supports a subset of:
/// https://github.com/flutter/flutter/blob/master/packages/flutter_tools/doc/daemon.md
class DaemonCommand extends Command<int> {
  @override
  final name = 'daemon';

  @override
  final hidden = true;

  @override
  String get description =>
      'A mode for running WebDev from command-line tools.';

  @override
  final argParser = ArgParser()
    ..addMultiOption('launch-app', help: 'The html file to launch in chrome.');

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

  @override
  Future<int> run() async {
    var configuration = Configuration.fromArgs(argResults,
        defaultConfiguration: Configuration(
            launchInChrome: true, debug: true, autoRun: false, release: false));
    configureLogWriter(configuration.verbose);
    // Validate the pubspec first to ensure we are in a Dart project.
    var pubspecLock = await readPubspecLock(configuration);

    Daemon? daemon;
    DevWorkflow? workflow;
    var cancelCount = 0;
    var cancelSub = StreamGroup.merge([
      ProcessSignal.sigint.watch(),
      // SIGTERM is not supported on Windows.
      Platform.isWindows ? const Stream.empty() : ProcessSignal.sigterm.watch()
    ]).listen((signal) async {
      cancelCount++;
      daemon?.shutdown();
      if (cancelCount > 1) exit(1);
    });
    try {
      daemon = Daemon(_stdinCommandStream, _stdoutCommandResponse);
      var daemonDomain = DaemonDomain(daemon);
      configureLogWriter(configuration.verbose, customLogWriter:
          (level, message, {loggerName, error, stackTrace, verbose}) {
        if (configuration.verbose || level >= Level.INFO) {
          daemonDomain.sendEvent('daemon.log', {
            'log': formatLog(
              level,
              message,
              loggerName: loggerName,
              error: error,
              stackTrace: stackTrace,
            )
          });
        }
      });
      daemon.registerDomain(daemonDomain);
      var buildOptions = buildRunnerArgs(pubspecLock, configuration);
      var extraArgs = argResults?.rest ?? [];
      var directoryArgs =
          extraArgs.where((arg) => !arg.startsWith('-')).toList();
      var targetPorts =
          parseDirectoryArgs(directoryArgs, basePort: await findUnusedPort());
      validateLaunchApps(configuration.launchApps, targetPorts.keys);

      workflow =
          await DevWorkflow.start(configuration, buildOptions, targetPorts);
      daemon.registerDomain(AppDomain(daemon, workflow.serverManager));
      await daemon.onExit;
      exitCode = 0;
      return 0;
    } catch (e) {
      daemon?.shutdown();
      exitCode = 1;
      rethrow;
    } finally {
      await workflow?.shutDown();
      // Only cancel this subscription after all shutdown work has completed.
      // https://github.com/dart-lang/sdk/issues/23074.
      await cancelSub.cancel();
      // For some reason Windows remains open due to what appears to be an
      // undrained `stdin`. Feel free to waste some time trying to remove this.
      if (Platform.isWindows) exit(exitCode);
    }
  }
}
