// Copyright (c) 2020, 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:cli_util/cli_logging.dart';
import 'package:path/path.dart' as path;

import 'experiments.dart';
import 'utils.dart';

// Initialize a default logger. We'll replace this with a verbose logger if
// necessary once we start parsing.
final Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
Logger log = Logger.standard(ansi: ansi);

bool isDiagnostics = false;

/// When set, this function is executed from the [DartdevCommand] constructor to
/// contribute additional flags.
void Function(ArgParser argParser, String cmdName)? flagContributor;

abstract class DartdevCommand extends Command<int> {
  static const errorExitCode = 65;

  final String _name;
  final String _description;
  final bool _verbose;
  final Project project = Project();

  @override
  final bool hidden;

  DartdevCommand(this._name, this._description, this._verbose,
      {this.hidden = false}) {
    flagContributor?.call(argParser, _name);
  }

  @override
  String get name => _name;

  @override
  String get description => _description;

  ArgParser? _argParser;

  @override
  ArgParser get argParser => _argParser ??= createArgParser();

  @override
  String get category {
    if (parent != null) {
      // Subcommands should not have a top level command category.
      assert(commandCategory == null);
      return '';
    }
    return commandCategory!.name;
  }

  CommandCategory? get commandCategory => null;

  @override
  String get invocation {
    String result = super.invocation;
    if (_verbose) {
      var firstSpace = result.indexOf(' ');
      if (firstSpace < 0) firstSpace = result.length;
      result = result.replaceRange(firstSpace, firstSpace, ' [vm-options]');
    }
    return result;
  }

  /// Create the ArgParser instance for this command.
  ///
  /// Subclasses can override this in order to create a customized ArgParser.
  ArgParser createArgParser() =>
      ArgParser(usageLineLength: dartdevUsageLineLength);
}

enum CommandCategory {
  global('Global'),
  project('Project'),
  sourceCode('Source code'),
  tools('Tools');

  final String name;

  const CommandCategory(this.name);
}

extension DartDevCommand<T> on Command<T> {
  /// Return whether commands should emit verbose output.
  bool get verbose => globalResults!.flag('verbose');

  /// Return whether the tool should emit diagnostic output.
  bool get diagnosticsEnabled => globalResults!.flag('diagnostics');

  /// Return whether any Dart experiments were specified by the user.
  bool get wereExperimentsSpecified =>
      globalResults?.wasParsed(experimentFlagName) ?? false;

  List<String> get specifiedExperiments =>
      globalResults!.multiOption(experimentFlagName);
}

Future<int> runProcess(
  List<String> command, {
  bool logToTrace = false,
  void Function(String str)? listener,
  String? cwd,
}) async {
  Future<void> forward(Stream<List<int>> output, bool isStderr) {
    return _streamLineTransform(output, (line) {
      final trimmed = line.trimRight();
      logToTrace
          ? log.trace(trimmed)
          : (isStderr ? log.stderr(trimmed) : log.stdout(trimmed));
      if (listener != null) listener(line);
    });
  }

  log.trace(command.join(' '));
  final process = await Process.start(
    command.first,
    command.skip(1).toList(),
    workingDirectory: cwd,
  );
  final (_, _, exitCode) = await (
    forward(process.stdout, false),
    forward(process.stderr, true),
    process.exitCode
  ).wait;
  return exitCode;
}

Future<void> _streamLineTransform(
  Stream<List<int>> stream,
  Function(String line) handler,
) {
  return stream
      .transform(utf8.decoder)
      .transform(const LineSplitter())
      .listen(handler)
      .asFuture();
}

/// A representation of a project on disk.
class Project {
  final Directory dir;

  Project() : dir = Directory.current;

  Project.fromDirectory(this.dir);

  bool get hasPubspecFile =>
      FileSystemEntity.isFileSync(path.join(dir.path, 'pubspec.yaml'));

  File get pubspecFile => File(path.join(dir.path, 'pubspec.yaml'));
}
