// Copyright 2019 The Fuchsia Authors. 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' as io;
import 'dart:math';
import 'package:fxtest/exceptions.dart';

abstract class StandardOut {
  void write(String line);
  void writeln(String line);
  Future<dynamic> get done;
  Future<dynamic> close();
}

class RealStandardOut implements StandardOut {
  @override
  void write(String line) => io.stdout.write(line);
  @override
  void writeln(String line) => io.stdout.writeln(line);
  @override
  Future<dynamic> get done => io.stdout.done;
  @override
  Future<dynamic> close() => io.stdout.close();
}

class LocMemStandardOut implements StandardOut {
  bool isOpen;
  final List<String> buffer;
  final Completer<dynamic> _done;
  LocMemStandardOut()
      : isOpen = true,
        buffer = [],
        _done = Completer<dynamic>();
  @override
  void write(String line) => isOpen
      // If the buffer is empty,
      ? buffer.isEmpty //
          // add the line as the first element
          ? buffer.add(line)
          // otherwise, append the line
          : buffer.last += line
      // And if we weren't even open, raise an error
      : throw io.StdoutException('IO is closed.');
  @override
  void writeln(String line) =>
      isOpen ? buffer.add(line) : throw io.StdoutException('IO is closed.');
  @override
  Future<dynamic> get done => _done.future;
  @override
  Future<dynamic> close() {
    isOpen = false;
    !_done.isCompleted
        ? _done.complete()
        : throw io.StdoutException('IO is already closed.');
    return _done.future;
  }
}

/// Wrapper around iteratively build command line output.
///
/// Uses control/escape sequences to reset output when necessary, but otherwise
/// simply appends new output to the end of previously written messages.
///
/// Usage:
///
/// ```dart
/// OutputBuffer outputBuffer = OutputBuffer(stdout: stdout);
///
/// // Prints "this will appear on its own line\n"
/// outputBuffer.addLine('this will appear on its own line');
///
/// // Prints "this will be added to an in-progress line"  (no newline!)
/// outputBuffer.addSubstring('this will be added to');
/// outputBuffer.addSubstring(' an in-progress line');
///
/// // Prints "\nbut now back to whole lines\n" (leading newline bc it followed
/// // a partial line, plus trailing)
/// outputBuffer.addLine('but now back to whole lines')
/// ```
class OutputBuffer {
  /// The actual stuff of our output. Can be built and flushed iteratively.
  final List<String> content;

  /// Helper which implements all necessary functions of [io.stdout].
  final StandardOut stdout;

  /// Set to `true` if we previously entered a trailing newline for cosmetic
  /// purposes. Useful when we hope to emit whole lines after emitting
  /// substrings.
  bool _isCursorOnNewline;

  /// Driver used to programmatically resolve a future that approximates
  /// `_stdout.done`.
  ///
  /// This is important because if the user runs `fx test | -head X`, where X
  /// is greater than the number of lines of output, then having awaited the
  /// future from `_stdout.done` will cause the program to hang. On the other
  /// hand, not awaiting that future causes the error to not be caught and
  /// bubble up as an unhandled exception.
  ///
  /// Thus, the only way to drive this ourselves is to expose both, 1) a future
  /// inside a completer, and 2) a method external actors can use to close said
  /// future. Calling classes make use of the [close] method once the test suite
  /// reaches its natural conclusion.
  final Completer _stdoutCompleter;

  /// OS-aware line splitting resource.
  final _splitter = LineSplitter();

  final _ansiEscape = String.fromCharCode(27);

  OutputBuffer._({
    this.stdout,

    // Controls how the buffer should receive its first content.
    // Does not have a visual impact immediately
    bool cursorStartsOnNewLine = false,
  })  : content = [],
        _stdoutCompleter = Completer(),
        _isCursorOnNewline = cursorStartsOnNewLine ?? false {
    /// Listen to the actual `stdout.done` future and resolve our approximation
    /// with an error if that closes before the test suite completes.
    stdout.done.catchError((err) => _closeFutureWithError());
  }

  factory OutputBuffer.realIO({bool cursorStartsOnNewLine}) {
    return OutputBuffer._(
      cursorStartsOnNewLine: cursorStartsOnNewLine,
      stdout: RealStandardOut(),
    );
  }

  factory OutputBuffer.locMemIO({bool cursorStartsOnNewLine}) {
    return OutputBuffer._(
      cursorStartsOnNewLine: cursorStartsOnNewLine,
      stdout: LocMemStandardOut(),
    );
  }

  void _closeFutureWithError() => !_stdoutCompleter.isCompleted
      ? _stdoutCompleter.completeError(OutputClosedException())
      : null;

  /// Future used to approximate when the stdout is closed
  Future stdOutClosedFuture() => _stdoutCompleter.future;

  /// Resolves the future that waits for the stdout to close. Use this when
  /// the test suite has reached its natural conclusion.
  void close() =>
      !_stdoutCompleter.isCompleted ? _stdoutCompleter.complete(true) : null;

  void forcefullyClose() => _closeFutureWithError();

  void _clearLines([int lines = 1]) {
    if (_isCursorOnNewline) {
      _cursorUp();
      _isCursorOnNewline = false;
    }

    int counter = 0;
    while (counter < lines) {
      _clearLine();
      if (counter < lines - 1) {
        _cursorUp();
      }
      counter++;
    }
  }

  void _clearLine() {
    stdout
      ..write('$_ansiEscape[2K') // clear line
      ..write('$_ansiEscape[0G'); // cursor to 0-index on current line
  }

  void _cursorUp() {
    stdout.write('$_ansiEscape[1A'); // cursor up
  }

  /// Appends additional characters to the last line of the buffer
  void addSubstring(String msg, {bool shouldFlush = true}) {
    if (content.isEmpty) {
      content.add('');
    }
    content.last += msg;

    if (shouldFlush) {
      stdout.write(msg);
      _isCursorOnNewline = false;
    }
  }

  /// Adds an additional line to the end of the buffer
  void addLine(String msg, {bool shouldFlush = true}) {
    addLines(_splitter.convert(msg), shouldFlush: shouldFlush);
  }

  /// Adds N additional lines to the end of the buffer
  void addLines(List<String> msgs, {bool shouldFlush = true}) {
    if (!_isCursorOnNewline) {
      stdout.writeln('');
      _isCursorOnNewline = true;
    }
    msgs.forEach(_registerLine);
    if (shouldFlush) {
      _flushLines(msgs);
    }
  }

  /// Gracefully handles adding lines that themselves contain newlines, since
  /// otherwise that breaks some assumptions.
  void _registerLine(String line) {
    content.addAll(_splitter.convert(line));
  }

  /// Replaces the content of individual lines in the buffer and, optionally,
  /// reflushes them to the [stdout].
  ///
  /// Assumes the passed list of strings should overlay the end of [buffer].
  /// Thus, if [buffer] is a list of 10 strings, and this function is invoked
  /// with a list of 3 strings, indices 7, 8, and 9 (the last three elements)
  /// will be replaced.
  void updateLines(List<String> msgs, {bool shouldFlush = true}) {
    while (msgs.length > content.length) {
      content.add('');
    }
    List<String> replacedLines = content.sublist(content.length - msgs.length);
    for (int count in Iterable<int>.generate(msgs.length)) {
      int indexToReplace = content.length - msgs.length + count;
      content[indexToReplace] = msgs[count];
    }

    if (shouldFlush) {
      var numToFlush = _getTerminalRowsFromLines(replacedLines);
      _clearLines(numToFlush);
      _flushLines(msgs);
    }
  }

  /// Calculates how much various strings had to wrap on the current terminal.
  ///
  /// This is important because printing one extra long sentence will wrap onto
  /// multiple rows in the terminal, but then clearing "a line" does not go back
  /// to the last newline -- but instead just clears a given terminal row.
  int _getTerminalRowsFromLines(List<String> lines) {
    if (!io.stdout.hasTerminal) {
      return lines.length;
    }
    var rowsPerLine = lines.fold<int>(0, (previousValue, line) {
      var bareLine = _stripAnsi(line).length;
      var numWholeLines = bareLine ~/ io.stdout.terminalColumns;
      var numPartialLines = bareLine % io.stdout.terminalColumns > 0 ? 1 : 0;
      return previousValue + numWholeLines + numPartialLines;
    });
    return max(rowsPerLine, lines.length);
  }

  String _stripAnsi(String val) {
    var re = RegExp(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]');
    return val.replaceAll(re, '');
  }

  /// Sends a list of strings to the [stdout]. Is completely unaware of the
  /// [buffer], so calling this directly can desync the internal state from what
  /// is rendered in the terminal.
  void _flushLines(List<String> lines) {
    stdout.writeln(lines.join('\n'));
    _isCursorOnNewline = true;
  }

  /// Scans the end of the buffer and sets the amount of trailing newlines
  /// (represented by empty strings in our list of strings) to the desired level.
  /// If the passed number is greater than the current number of empty lines,
  /// an appropriate amount of newlines are added.
  void reduceEmptyRowsTo(int number) {
    bool stillLookingForLineWithContent = true;
    int depth = 0;
    while (stillLookingForLineWithContent) {
      if (content[content.length - depth - 1].isEmpty) {
        depth += 1;
      } else {
        stillLookingForLineWithContent = false;
      }
    }
    if (depth > number) {
      _clearLines(depth - number);
    } else if (depth <= number) {
      var emptyLines = <String>[];
      for (var counter = 0; counter < (number - depth + 1); counter++) {
        emptyLines.add('');
      }
      addLines(emptyLines);
    }
  }

  /// Writes the entire [buffer] to the [stdout].
  void flush({int start, int end}) {
    _flushLines(content.sublist(start ?? 0, end ?? content.length));
  }

  /// Clears the [stdout], without touching the [buffer]. If you are not
  /// planning to re-flush, you should consider also resetting [buffer].
  void clear() {
    int allRows = _getTerminalRowsFromLines(content);
    // If the cursor is currently on a new line, deleting *all* the lines will
    // go so far back as to delete the original prompt
    _clearLines(_isCursorOnNewline ? allRows : allRows - 1);
  }
}
