// 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 '../pubspec.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 {
    final 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.
    try {
      await validatePubspecLock(configuration);
    } on PackageException catch (e) {
      logWriter(Level.SEVERE, 'Pubspec errors: ', error: '${e.details}');
      rethrow;
    }

    Daemon? daemon;
    DevWorkflow? workflow;
    var cancelCount = 0;
    final 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);
      final 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);
      final buildOptions = buildRunnerArgs(configuration);
      final extraArgs = argResults?.rest ?? [];
      final directoryArgs =
          extraArgs.where((arg) => !arg.startsWith('-')).toList();
      final 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);
    }
  }
}
