// Copyright (c) 2014, 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.

library commando;

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';

import 'package:ddbg/terminfo.dart';

typedef List<String> CommandCompleter(List<String> commandParts);

class Commando {
  // Ctrl keys
  static const runeCtrlA   = 0x01;
  static const runeCtrlB   = 0x02;
  static const runeCtrlD   = 0x04;
  static const runeCtrlE   = 0x05;
  static const runeCtrlF   = 0x06;
  static const runeTAB     = 0x09;
  static const runeNewline = 0x0a;
  static const runeCtrlK   = 0x0b;
  static const runeCtrlL   = 0x0c;
  static const runeCtrlN   = 0x0e;
  static const runeCtrlP   = 0x10;
  static const runeCtrlU   = 0x15;
  static const runeCtrlY   = 0x19;
  static const runeESC     = 0x1b;
  static const runeSpace   = 0x20;
  static const runeDEL     = 0x7F;

  StreamController<String> _commandController;

  Stream get commands => _commandController.stream;

  Commando({consoleIn,
            consoleOut,
            this.prompt : '> ',
          this.completer : null}) {
    _stdin = (consoleIn != null ? consoleIn : stdin);
    _stdout = (consoleOut != null ? consoleOut : stdout);
    _commandController = new StreamController<String>(
        onCancel: _onCancel);
    _stdin.echoMode = false;
    _stdin.lineMode = false;
    _screenWidth = _term.cols - 1;
    _writePrompt();
    // TODO(turnidge): Handle errors in _stdin here.
    _stdinSubscription =
        _stdin.transform(UTF8.decoder).listen(_handleText, onDone:_done);
  }

  Future _onCancel() {
    _stdin.echoMode = true;
    _stdin.lineMode = true;
    var future = _stdinSubscription.cancel();
    if (future != null) {
      return future;
    } else {
      return new Future.value();
    }
  }

  // Before terminating, call close() to restore terminal settings.
  void _done() {
    _onCancel().then((_) {
        _commandController.close();
      });
  }
  
  void _handleText(String text) {
    try {
      if (!_promptShown) {
        _bufferedInput.write(text);
        return;
      }

      var runes = text.runes.toList();
      var pos = 0;
      while (pos < runes.length) {
        if (!_promptShown) {
          // A command was processed which hid the prompt.  Buffer
          // the rest of the input.
          //
          // TODO(turnidge): Here and elsewhere in the file I pass
          // runes to String.fromCharCodes.  Does this work?
          _bufferedInput.write(
              new String.fromCharCodes(runes.skip(pos)));
          return;
        }

        var rune = runes[pos];

        // Count consecutive tabs because double-tab is meaningful.
        if (rune == runeTAB) {
          _tabCount++;
        } else {
          _tabCount = 0;
        }

        if (_isControlRune(rune)) {
          pos += _handleControlSequence(runes, pos);
        } else {
          pos += _handleRegularSequence(runes, pos);
        }
      }
    } catch(e, trace) {
      _commandController.addError(e, trace);
    }
  }

  int _handleControlSequence(List<int> runes, int pos) {
    var runesConsumed = 1;  // Most common result.
    var char = runes[pos];
    switch (char) {
      case runeCtrlA:
        _home();
        break;
           
      case runeCtrlB:
        _leftArrow();
        break;

      case runeCtrlD:
        if (_currentLine.length == 0) {
          // ^D on an empty line means quit.
          _stdout.writeln("^D");
          _done();
        } else {
          _delete();
        }
        break;
           
      case runeCtrlE:
        _end();
        break;
           
      case runeCtrlF:
        _rightArrow();
        break;

      case runeTAB:
        _complete(_tabCount > 1);
        break;
      
      case runeNewline:
        _newline();
        break;
      
      case runeCtrlK:
        _kill();
        break;
           
      case runeCtrlL:
        _clearScreen();
        break;
           
      case runeCtrlN:
        _historyNext();
        break;

      case runeCtrlP:
        _historyPrevious();
        break;

      case runeCtrlU:
        _clearLine();
        break;
           
      case runeCtrlY:
        _yank();
        break;
           
      case runeESC:
        // Check to see if this is an arrow key.
        if (pos + 2 < runes.length &&  // must be a 3 char sequence.
            runes[pos + 1] == 0x5b) {  // second char must be '['.
          switch (runes[pos + 2]) {
            case 0x41:  // ^[[A = up arrow
              _historyPrevious();
              runesConsumed = 3;
              break;

            case 0x42:  // ^[[B = down arrow
              _historyNext();
              runesConsumed = 3;
              break;

            case 0x43:  // ^[[C = right arrow
              _rightArrow();
              runesConsumed = 3;
              break;
        
            case 0x44:  // ^[[D = left arrow
              _leftArrow();
              runesConsumed = 3;
              break;

            default:
              // Ignore the escape character.
              break;
          }
        }
        break;

      case runeDEL:
        _backspace();
        break;

      default:
        // Ignore the escape character.
        break;
    }
    return runesConsumed;
  }

  int _handleRegularSequence(List<int> runes, int pos) {
    var len = pos + 1;
    while (len < runes.length && !_isControlRune(runes[len])) {
      len++;
    }
    _addChars(runes.getRange(pos, len));
    return len;
  }

  bool _isControlRune(int char) {
    return (char >= 0x00 && char < 0x20) || (char == 0x7f);
  }

  void _writePromptAndLine() {
    _writePrompt();
    var pos = _writeRange(_currentLine, 0, _currentLine.length);
    _cursorPos = _move(pos, _cursorPos);
  }

  void _writePrompt() {
    _stdout.write(prompt);
  }

  void _addChars(Iterable<int> chars) {
    var newLine = [];
    newLine..addAll(_currentLine.take(_cursorPos))
           ..addAll(chars)
           ..addAll(_currentLine.skip(_cursorPos));
    _update(newLine, (_cursorPos + chars.length));
  }

  void _backspace() {
    if (_cursorPos == 0) {
      return;
    }

    var newLine = [];
    newLine..addAll(_currentLine.take(_cursorPos - 1))
           ..addAll(_currentLine.skip(_cursorPos));
    _update(newLine, (_cursorPos - 1));
  }

  void _delete() {
    if (_cursorPos == _currentLine.length) {
      return;
    }

    var newLine = [];
    newLine..addAll(_currentLine.take(_cursorPos))
           ..addAll(_currentLine.skip(_cursorPos + 1));
    _update(newLine, _cursorPos);
  }

  void _home() {
    _updatePos(0);
  }

  void _end() {
    _updatePos(_currentLine.length);
  }

  void _clearScreen() {
    _stdout.write(_term.clear);
    _term.resize();
    _screenWidth = _term.cols - 1;
    _writePromptAndLine();
  }

  void _kill() {
    var newLine = [];
    newLine.addAll(_currentLine.take(_cursorPos));
    _killBuffer = _currentLine.skip(_cursorPos).toList();
    _update(newLine, _cursorPos);
  }

  void _clearLine() {
    _update([], 0);
  }

  void _yank() {
    var newLine = [];
    newLine..addAll(_currentLine.take(_cursorPos))
           ..addAll(_killBuffer)
           ..addAll(_currentLine.skip(_cursorPos));
    _update(newLine, (_cursorPos + _killBuffer.length));
  }

  static String _trimLeadingSpaces(String line) {
    bool _isSpace(int rune) {
      return rune == runeSpace;
    }
    return new String.fromCharCodes(line.runes.skipWhile(_isSpace));
  }

  static String _sharedPrefix(String one, String two) {
    var len = min(one.length, two.length);
    var runesOne = one.runes.toList();
    var runesTwo = two.runes.toList();
    var pos;
    for (pos = 0; pos < len; pos++) {
      if (runesOne[pos] != runesTwo[pos]) {
        break;
      }
    }
    var shared =  new String.fromCharCodes(runesOne.take(pos));
    return shared;
  }

  void _complete(bool showCompletions) {
    if (completer == null) {
      return;
    }

    var linePrefix = _currentLine.take(_cursorPos).toList();
    var lineAsString = new String.fromCharCodes(linePrefix);
    var commandParts = new List.from(lineAsString.split(' ').where((line) {
          return line != ' ' && line != '';
        }));
    if (lineAsString.endsWith(' ')) {
      // If the current line ends with a space, they are hoping to
      // complete the next word in the command.  Add an empty string
      // to the commandParts to signal this to the completer.
      commandParts.add('');
    }
    List<String> completionList = completer(commandParts);
    var completion = null;

    if (completionList.length == 0) {
      // The current line admits no possible completion.
      return;

    } else if (completionList.length == 1) {
      // There is a single, non-ambiguous completion for the current line.
      completion = completionList[0];

    } else {
      // There are ambiguous completions. Find the longest common
      // shared prefix of all of the completions.
      completion = completionList.fold(completionList[0], _sharedPrefix);
    }

    if (showCompletions) {
      // User hit double-TAB.  Show them all possible completions.
      completionList.sort((a,b) => a.compareTo(b));
      _move(_cursorPos, _currentLine.length);
      _stdout.writeln();
      _stdout.writeln(completionList);
      _writePromptAndLine();
      return;

    } else {
      // Apply the current completion.
      var completionRunes = completion.runes.toList();

      var newLine = [];
      newLine..addAll(completionRunes)
             ..addAll(_currentLine.skip(_cursorPos));
      _update(newLine, completionRunes.length);
      return;
    }
  }

  void _newline() {
    _addLineToHistory(_currentLine);
    _linePos = _lines.length;

    _end();
    _stdout.writeln();

    // Call the user's command handler.
    _commandController.add(new String.fromCharCodes(_currentLine));
    
    _currentLine = [];
    _cursorPos = 0;
    if (_promptShown) {
      _writePrompt();
    }
  }

  void _leftArrow() {
    _updatePos(_cursorPos - 1);
  }

  void _rightArrow() {
    _updatePos(_cursorPos + 1);
  }

  void _addLineToHistory(List<int> line) {
    if (_tempLineAdded) {
      _lines.removeLast();
      _tempLineAdded = false;
    }
    if (line.length > 0) {
      _lines.add(line);
    }
  }

  void _addTempLineToHistory(List<int> line) {
    _lines.add(line);
    _tempLineAdded = true;
  }

  void _replaceHistory(List<int> line, int linePos) {
    _lines[linePos] = line;
  }

  void _historyPrevious() {
    if (_linePos == 0) {
      return;
    }

    if (_linePos == _lines.length) {
      // The current in-progress line gets temporarily stored in history.
      _addTempLineToHistory(_currentLine);
    } else {
      // Any edits get committed to history.
      _replaceHistory(_currentLine, _linePos);
    }

    _linePos -= 1;
    var line = _lines[_linePos];
    _update(line, line.length);
  }

  void _historyNext() {
    // For the very first command, _linePos (0) will exceed
    // (_lines.length - 1) (-1) so we use a ">=" here instead of an "==".
    if (_linePos >= (_lines.length - 1)) {
      return;
    }

    // Any edits get committed to history.
    _replaceHistory(_currentLine, _linePos);

    _linePos += 1;
    var line = _lines[_linePos];
    _update(line, line.length);
  }

  void _updatePos(int newCursorPos) {
    if (newCursorPos < 0) {
      return;
    }
    if (newCursorPos > _currentLine.length) {
      return;
    }

    _cursorPos = _move(_cursorPos, newCursorPos);
  }

  void _update(List<int> newLine, int newCursorPos) {
    var pos = _cursorPos;
    var diffPos;
    var sharedLen = min(_currentLine.length, newLine.length);

    // Find first difference.
    for (diffPos = 0; diffPos < sharedLen; diffPos++) {
      if (_currentLine[diffPos] != newLine[diffPos]) {
        break;
      }
    }

    // Move the cursor to where the difference begins.
    pos = _move(pos, diffPos);

    // Write the new text.
    pos = _writeRange(newLine, pos, newLine.length);

    // Clear any extra characters at the end.
    pos = _clearRange(pos, _currentLine.length);

    // Move the cursor back to the input point.
    _cursorPos = _move(pos, newCursorPos);
    _currentLine = newLine;    
  }

  void print(String text) {
    bool togglePrompt = _promptShown;
    if (togglePrompt) {
      hide();
    }
    _stdout.writeln(text);
    if (togglePrompt) {
      show();
    }
  }
  
  void hide() {
    if (!_promptShown) {
      return;
    }
    _promptShown = false;
    // We need to erase everything, including the prompt.
    var curLine = _getLine(_cursorPos);
    var lastLine = _getLine(_currentLine.length);

    // Go to last line.
    if (curLine < lastLine) {
      for (var i = 0; i < (lastLine - curLine); i++) {
        // This moves us to column 0.
        _stdout.write(_term.cursorDown);
      }
      curLine = lastLine;
    } else {
      // Move to column 0.
      _stdout.write('\r');
    }

    // Work our way up, clearing lines.
    while (true) {
      _stdout.write(_term.clrEOL);
      if (curLine > 0) {
        _stdout.write(_term.cursorUp);
      } else {
        break;
      }
    }
  }

  void show() {
    if (_promptShown) {
      return;
    }
    _promptShown = true;
    _writePromptAndLine();

    // If input was buffered while the prompt was hidden, process it
    // now.
    if (!_bufferedInput.isEmpty) {
      var input = _bufferedInput.toString();
      _bufferedInput.clear();
      _handleText(input);
    }
  }

  int _writeRange(List<int> text, int pos, int writeToPos) {
    if (pos >= writeToPos) {
      return pos;
    }
    while (pos < writeToPos) {
      var margin = _nextMargin(pos);
      var limit = min(writeToPos, margin);
      _stdout.write(new String.fromCharCodes(text.getRange(pos, limit)));
      pos = limit;
      if (pos == margin) {
        _stdout.write('\n');
      }
    }
    return pos;
  }

  int _clearRange(int pos, int clearToPos) {
    if (pos >= clearToPos) {
      return pos;
    }
    while (true) {
      var limit = _nextMargin(pos);
      _stdout.write(_term.clrEOL);
      if (limit >= clearToPos) {
        return pos;
      }
      _stdout.write('\n');
      pos = limit;
    }
  }

  int _move(int pos, int newPos) {
    if (pos == newPos) {
      return pos;
    }

    var curCol = _getCol(pos);
    var curLine = _getLine(pos);
    var newCol = _getCol(newPos);
    var newLine = _getLine(newPos);

    if (curLine > newLine) {
      for (var i = 0; i < (curLine - newLine); i++) {
        _stdout.write(_term.cursorUp);
      }
    }
    if (curLine < newLine) {
      for (var i = 0; i < (newLine - curLine); i++) {
        _stdout.write(_term.cursorDown);
      }

      // Moving down resets column to zero, oddly.
      curCol = 0;
    }
    if (curCol > newCol) {
      for (var i = 0; i < (curCol - newCol); i++) {
        _stdout.write(_term.cursorBack);
      }
    }
    if (curCol < newCol) {
      for (var i = 0; i < (newCol - curCol); i++) {
        _stdout.write(_term.cursorForward);
      }
    }

    return newPos;
  }
        
  int _nextMargin(int pos) {
    var truePos = pos + prompt.length;
    return ((truePos ~/ _screenWidth) + 1) * _screenWidth - prompt.length;
  }

  int _getLine(int pos) {
    var truePos = pos + prompt.length;
    return truePos ~/ _screenWidth;
  }

  int _getCol(int pos) {
    var truePos = pos + prompt.length;
    return truePos % _screenWidth;
  }

  Stdin _stdin;
  StreamSubscription _stdinSubscription;
  IOSink _stdout;
  final String prompt;
  bool _promptShown = true;
  final CommandCompleter completer;
  TermInfo _term = new TermInfo();

  // TODO(turnidge): See if we can get screen resize events.
  int _screenWidth;
  List<int> _currentLine = [];  // A list of runes.
  StringBuffer _bufferedInput = new StringBuffer();
  List<List<int>> _lines = [];

  // When using the command history, the current line is temporarily
  // added to the history to allow the user to return to it.  This
  // values tracks whether the history has a temporary line at the end.
  bool _tempLineAdded = false;
  int _linePos = 0;
  int _cursorPos = 0;
  int _tabCount = 0;
  List<int> _killBuffer = [];
}


// Demo code.


List<String> _myCompleter(List<String> commandTokens) {
  List<String> completions = new List<String>();

  // First word completions.
  if (commandTokens.length <= 1) {
    String prefix = '';
    if (commandTokens.length == 1) {
      prefix = commandTokens.first;
    }
    if ('quit'.startsWith(prefix)) {
      completions.add('quit');
    }
    if ('help'.startsWith(prefix)) {
      completions.add('help');
    }
    if ('happyface'.startsWith(prefix)) {
      completions.add('happyface');
    }
  }

  // Complete 'foobar' or 'gondola' anywhere in string.
  String lastWord = commandTokens.last;
  if ('foobar'.startsWith(lastWord)) {
    completions.add('foobar');
  }
  if ('gondola'.startsWith(lastWord)) {
    completions.add('gondola');
  }

  return completions;
}


int _helpCount = 0;
Commando cmdo;
var cmdoSubscription;


void _handleCommand(String rawCommand) {
  String command = rawCommand.trim();
  cmdo.hide();
  if (command == 'quit') {
    var future = cmdoSubscription.cancel();
    if (future != null) {
      future.then((_) {
          print('Exiting');
          exit(0);
        });
    } else {
      print('Exiting');
      exit(0);
    }
  } else if (command == 'help') {
    switch (_helpCount) {
      case 0:
        print('I will not help you.');
        break;
      case 1:
        print('I mean it.');
        break;
      case 2:
        print('Seriously.');
        break;
      case 100:
        print('Well now.');
        break;
      default:
        print("Okay.  Type 'quit' to quit");
        break;
    }
    _helpCount++;
  } else if (command == 'happyface') {
    print(':-)');
  } else {
    print('Received command($command)');
  }
  cmdo.show();
}


void main() {
  print('[Commando demo]');
  cmdo = new Commando(completer:_myCompleter);
  cmdoSubscription = cmdo.commands.listen(_handleCommand);
}
