// Copyright (c) 2017, 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 'package:path/path.dart' as p;
import 'package:term_glyph/term_glyph.dart' as glyph;
import 'package:test/test.dart';

import 'descriptor.dart';
import 'sandbox.dart';

/// A UTF-8 codec that allows malformed byte sequences.
final utf8 = const Utf8Codec(allowMalformed: true);

/// Prepends a vertical bar to [text].
String addBar(String text) => prefixLines(text, "${glyph.verticalLine} ",
    first: "${glyph.downEnd} ", last: "${glyph.upEnd} ", single: "| ");

/// Indents [text], and adds a bullet at the beginning.
String addBullet(String text) =>
    prefixLines(text, "  ", first: "${glyph.bullet} ");

/// Converts [strings] to a bulleted list.
String bullet(Iterable<String> strings) => strings.map(addBullet).join("\n");

/// Returns a human-readable description of a directory with the given [name]
/// and [contents].
String describeDirectory(String name, List<Descriptor> contents) {
  if (contents.isEmpty) return name;

  var buffer = StringBuffer();
  buffer.writeln(name);
  for (var entry in contents.take(contents.length - 1)) {
    var entryString = prefixLines(entry.describe(), '${glyph.verticalLine}   ',
        first: '${glyph.teeRight}${glyph.horizontalLine}'
            '${glyph.horizontalLine} ');
    buffer.writeln(entryString);
  }

  var lastEntryString = prefixLines(contents.last.describe(), '    ',
      first: '${glyph.bottomLeftCorner}${glyph.horizontalLine}'
          '${glyph.horizontalLine} ');
  buffer.write(lastEntryString);
  return buffer.toString();
}

/// Prepends each line in [text] with [prefix].
///
/// If [first] or [last] is passed, the first and last lines, respectively, are
/// prefixed with those instead. If [single] is passed, it's used if there's
/// only a single line; otherwise, [first], [last], or [prefix] is used, in that
/// order of precedence.
String prefixLines(String text, String prefix,
    {String first, String last, String single}) {
  first ??= prefix;
  last ??= prefix;
  single ??= first ?? last ?? prefix;

  var lines = text.split('\n');
  if (lines.length == 1) return "$single$text";

  var buffer = StringBuffer("$first${lines.first}\n");
  for (var line in lines.skip(1).take(lines.length - 2)) {
    buffer.writeln("$prefix$line");
  }
  buffer.write("$last${lines.last}");
  return buffer.toString();
}

/// Returns a representation of [path] that's easy for humans to read.
///
/// This may not be a valid path relative to [p.current].
String prettyPath(String path) {
  if (sandboxExists && p.isWithin(sandbox, path)) {
    return p.relative(path, from: sandbox);
  } else if (p.isWithin(p.current, path)) {
    return p.relative(path);
  } else {
    return path;
  }
}

/// Returns whether [pattern] matches all of [string].
bool matchesAll(Pattern pattern, String string) =>
    pattern.matchAsPrefix(string)?.end == string.length;

/// Like [Future.wait] with `eagerError: true`, but reports errors after the
/// first using [registerException] rather than silently ignoring them.
Future<List<T>> waitAndReportErrors<T>(Iterable<Future<T>> futures) {
  var errored = false;
  return Future.wait(futures.map((future) {
    // Avoid async/await so that we synchronously add error handlers for the
    // futures to keep them from top-leveling.
    return future.catchError((error, StackTrace stackTrace) {
      if (!errored) {
        errored = true;
        throw error;
      } else {
        registerException(error, stackTrace);
      }
    });
  }));
}
