// Copyright (c) 2016, 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:io';
import 'dart:math' as math;

import 'package:async/async.dart';
import 'package:pedantic/pedantic.dart';

import '../util/io.dart';

/// An interactive console for taking user commands.
class Console {
  /// The registered commands.
  final _commands = <String, _Command>{};

  /// The pending next line of standard input, if we're waiting on one.
  CancelableOperation? _nextLine;

  /// Whether the console is currently running.
  bool _running = false;

  /// The terminal escape for red text, or the empty string if this is Windows
  /// or not outputting to a terminal.
  final String _red;

  /// The terminal escape for bold text, or the empty string if this is
  /// Windows or not outputting to a terminal.
  final String _bold;

  /// The terminal escape for removing test coloring, or the empty string if
  /// this is Windows or not outputting to a terminal.
  final String _noColor;

  /// Creates a new [Console].
  ///
  /// If [color] is true, this uses Unix terminal colors.
  Console({bool color = true})
      : _red = color ? '\u001b[31m' : '',
        _bold = color ? '\u001b[1m' : '',
        _noColor = color ? '\u001b[0m' : '' {
    registerCommand('help', 'Displays this help information.', _displayHelp);
  }

  /// Registers a command to be run whenever the user types [name].
  ///
  /// The [description] should be a one-line description of the command to print
  /// in the help output. The [body] callback will be called when the user types
  /// the command, and may return a [Future].
  void registerCommand(
      String name, String description, dynamic Function() body) {
    if (_commands.containsKey(name)) {
      throw ArgumentError('The console already has a command named "$name".');
    }

    _commands[name] = _Command(name, description, body);
  }

  /// Starts running the console.
  ///
  /// This prints the initial prompt and loops while waiting for user input.
  void start() {
    _running = true;
    unawaited(() async {
      while (_running) {
        stdout.write('> ');
        _nextLine = stdinLines.cancelable((queue) => queue.next);
        var commandName = await _nextLine!.value;
        _nextLine = null;

        var command = _commands[commandName];
        if (command == null) {
          stderr.writeln(
              '${_red}Unknown command $_bold$commandName$_noColor$_red.'
              '$_noColor');
        } else {
          await command.body();
        }
      }
    }());
  }

  /// Stops the console running.
  void stop() {
    _running = false;
    if (_nextLine != null) {
      stdout.writeln();
      _nextLine!.cancel();
    }
  }

  /// Displays the help info for the console commands.
  void _displayHelp() {
    var maxCommandLength =
        _commands.values.map((command) => command.name.length).reduce(math.max);

    for (var command in _commands.values) {
      var name = command.name.padRight(maxCommandLength + 4);
      print('$_bold$name$_noColor${command.description}');
    }
  }
}

/// An individual console command.
class _Command {
  /// The name of the command.
  final String name;

  /// The single-line description of the command.
  final String description;

  /// The callback to run when the command is invoked.
  final Function body;

  _Command(this.name, this.description, this.body);
}
