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

import 'package:async/async.dart';
import 'package:path/path.dart' as p;
import 'package:test_api/src/backend/compiler.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/operating_system.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports

import 'pretty_print.dart';

/// The default line length for output when there isn't a terminal attached to
/// stdout.
const _defaultLineLength = 200;

/// Whether the test runner is running on Google-internal infrastructure.
final bool inGoogle = Platform.version.contains('(google3)');

/// The maximum line length for output.
final int lineLength = () {
  try {
    return stdout.terminalColumns;
  } on UnsupportedError {
    // This can throw an [UnsupportedError] if we're running in a JS context
    // where `dart:io` is unavailable.
    return _defaultLineLength;
  } on StdoutException {
    return _defaultLineLength;
  }
}();

/// The root directory of the Dart SDK.
final String sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));

/// The current operating system.
final currentOS = OperatingSystem.findByIoName(Platform.operatingSystem);

/// Returns a [SuitePlatform] with the given [runtime], and with
/// [SuitePlatform.os] and [inGoogle] determined automatically.
///
/// If [runtime] is a browser, this will set [SuitePlatform.os] to
/// [OperatingSystem.none].
// TODO: https://github.com/dart-lang/test/issues/2119 - require compiler
SuitePlatform currentPlatform(Runtime runtime, [Compiler? compiler]) =>
    SuitePlatform(runtime,
        compiler: compiler,
        os: runtime.isBrowser ? OperatingSystem.none : currentOS,
        inGoogle: inGoogle);

/// A transformer that decodes bytes using UTF-8 and splits them on newlines.
final lineSplitter = StreamTransformer<List<int>, String>(
    (stream, cancelOnError) => utf8.decoder
        .bind(stream)
        .transform(const LineSplitter())
        .listen(null, cancelOnError: cancelOnError));

/// A queue of lines of standard input.
///
/// Also returns an empty stream for Fuchsia since Fuchsia components can't
/// access stdin.
StreamQueue<String> get stdinLines =>
    _stdinLines ??= StreamQueue(Platform.isFuchsia
        ? const Stream<String>.empty()
        : lineSplitter.bind(stdin));

StreamQueue<String>? _stdinLines;

/// Call cancel on [stdinLines], but only if it's been accessed previously.
void cancelStdinLines() => _stdinLines?.cancel(immediate: true);

/// Whether this is being run as a subprocess in the test package's own tests.
bool inTestTests = Platform.environment['_DART_TEST_TESTING'] == 'true';

/// The root directory below which to nest temporary directories created by the
/// test runner.
///
/// This is configurable so that the test code can validate that the runner
/// cleans up after itself fully.
final _tempDir = Platform.environment.containsKey('_UNITTEST_TEMP_DIR')
    ? Platform.environment['_UNITTEST_TEMP_DIR']!
    : Directory.systemTemp.path;

/// Whether or not the current terminal supports ansi escape codes.
///
/// Otherwise only printable ASCII characters should be used.
bool get canUseSpecialChars =>
    (!Platform.isWindows || stdout.supportsAnsiEscapes) && !inTestTests;

/// Detect whether we're running in a Github Actions context.
///
/// See
/// https://docs.github.com/en/actions/learn-github-actions/environment-variables.
bool get inGithubContext => Platform.environment['GITHUB_ACTIONS'] == 'true';

/// Creates a temporary directory and returns its path.
String createTempDir() =>
    Directory(_tempDir).createTempSync('dart_test_').resolveSymbolicLinksSync();

/// Creates a temporary directory and passes its path to [fn].
///
/// Once the [Future] returned by [fn] completes, the temporary directory and
/// all its contents are deleted. [fn] can also return `null`, in which case
/// the temporary directory is deleted immediately afterwards.
///
/// Returns a future that completes to the value that the future returned from
/// [fn] completes to.
Future withTempDir(Future Function(String) fn) {
  return Future.sync(() {
    var tempDir = createTempDir();
    return Future.sync(() => fn(tempDir))
        .whenComplete(() => Directory(tempDir).deleteWithRetry());
  });
}

/// Wraps [text] so that it fits within [lineLength].
///
/// This preserves existing newlines and doesn't consider terminal color escapes
/// part of a word's length. It only splits words on spaces, not on other sorts
/// of whitespace.
String wordWrap(String text) {
  return text.split('\n').map((originalLine) {
    var buffer = StringBuffer();
    var lengthSoFar = 0;
    for (var word in originalLine.split(' ')) {
      var wordLength = withoutColors(word).length;
      if (wordLength > lineLength) {
        if (lengthSoFar != 0) buffer.writeln();
        buffer.writeln(word);
      } else if (lengthSoFar == 0) {
        buffer.write(word);
        lengthSoFar = wordLength;
      } else if (lengthSoFar + 1 + wordLength > lineLength) {
        buffer.writeln();
        buffer.write(word);
        lengthSoFar = wordLength;
      } else {
        buffer.write(' $word');
        lengthSoFar += 1 + wordLength;
      }
    }
    return buffer.toString();
  }).join('\n');
}

/// Print a warning containing [message].
///
/// This automatically wraps lines if they get too long. If [color] is passed,
/// it controls whether the warning header is color; otherwise, it defaults to
/// [canUseSpecialChars].
///
/// If [print] is `true`, this prints the message using [print] to associate it
/// with the current test. Otherwise, it prints it using [stderr].
void warn(String message, {bool? color, bool print = false}) {
  color ??= canUseSpecialChars;
  var header = color ? '\u001b[33mWarning:\u001b[0m' : 'Warning:';
  (print ? core.print : stderr.writeln)(wordWrap('$header $message\n'));
}

/// Repeatedly finds a probably-unused port on localhost and passes it to
/// [tryPort] until it binds successfully.
///
/// [tryPort] should return a non-`null` value or a Future completing to a
/// non-`null` value once it binds successfully. This value will be returned
/// by [getUnusedPort] in turn.
///
/// This is necessary for ensuring that our port binding isn't flaky for
/// applications that don't print out the bound port.
Future<T> getUnusedPort<T extends Object>(
    FutureOr<T> Function(int port) tryPort) async {
  T? value;
  await Future.doWhile(() async {
    value = await tryPort(await getUnsafeUnusedPort());
    return value == null;
  });
  return value!;
}

/// Whether this computer supports binding to IPv6 addresses.
var _maySupportIPv6 = true;

/// Returns a port that is probably, but not definitely, not in use.
///
/// This has a built-in race condition: another process may bind this port at
/// any time after this call has returned. If at all possible, callers should
/// use [getUnusedPort] instead.
Future<int> getUnsafeUnusedPort() async {
  late int port;
  if (_maySupportIPv6) {
    try {
      final socket = await ServerSocket.bind(InternetAddress.loopbackIPv6, 0,
          v6Only: true);
      port = socket.port;
      await socket.close();
    } on SocketException {
      _maySupportIPv6 = false;
    }
  }
  if (!_maySupportIPv6) {
    final socket = await RawServerSocket.bind(InternetAddress.loopbackIPv4, 0);
    port = socket.port;
    await socket.close();
  }
  return port;
}

/// Returns the full URL of the Chrome remote debugger for the main page.
///
/// This takes the [base] remote debugger URL (which points to a browser-wide
/// page) and uses its JSON API to find the resolved URL for debugging the host
/// page.
Future<Uri> getRemoteDebuggerUrl(Uri base) async {
  try {
    var client = HttpClient();
    var request = await client.getUrl(base.resolve('/json/list'));
    var response = await request.close();
    var jsonObject =
        await json.fuse(utf8).decoder.bind(response).single as List;
    return base
        .resolve((jsonObject.first as Map)['devtoolsFrontendUrl'] as String);
  } catch (_) {
    // If we fail to talk to the remote debugger protocol, give up and return
    // the raw URL rather than crashing.
    return base;
  }
}

extension RetryDelete on FileSystemEntity {
  Future<void> deleteWithRetry() async {
    var attempt = 0;
    while (true) {
      try {
        await delete(recursive: true);
        return;
      } on FileSystemException {
        if (attempt == 2) rethrow;
        attempt++;
        await Future<void>.delayed(
            Duration(milliseconds: pow(10, attempt).toInt()));
      }
    }
  }
}

extension WindowsFilePaths on String {
  /// Strip out the leading slash before the drive letter on windows.
  ///
  /// In some windows environments full paths get passed with `/` before the
  /// drive letter. Normalize paths to exclude this slash when it exists.
  String get stripDriveLetterLeadingSlash {
    if (Platform.isWindows &&
        startsWith('/') &&
        length >= 3 &&
        this[2] == ':') {
      return substring(1);
    }
    return this;
  }
}
