// 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: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.
const utf8 = 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;

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

  final 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,
}) {
  single ??= first ?? last ?? prefix;
  first ??= prefix;
  last ??= prefix;

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

  final 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.
          future.catchError(
        // ignore: body_might_complete_normally_catch_error
        (Object error, StackTrace stackTrace) {
          if (!errored) {
            errored = true;
            throw error; // ignore: only_throw_errors
          } else {
            registerException(error, stackTrace);
          }
        },
      ),
    ),
  );
}
