// 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:core' as core;
import 'dart:core';
import 'dart:convert';
import 'dart:io';

import 'package:async/async.dart';
import 'package:path/path.dart' as p;

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 'package:test_api/src/utils.dart'; // ignore: implementation_imports

/// 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 unavaiable.
    return _defaultLineLength;
  } on StdoutException {
    return _defaultLineLength;
  }
}();

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

/// Returns the current operating system.
final OperatingSystem currentOS = (() {
  var name = Platform.operatingSystem;
  var os = OperatingSystem.findByIoName(name);
  if (os != null) return os;

  throw UnsupportedError('Unsupported operating system "$name".');
})();

/// Returns a [SuitePlatform] with the given [runtime], and with [os] and
/// [inGoogle] determined automatically.
///
/// If [runtime] is a browser, this will set [os] to [OperatingSystem.none].
SuitePlatform currentPlatform(Runtime runtime) => SuitePlatform(runtime,
    os: runtime.isBrowser ? OperatingSystem.none : currentOS,
    inGoogle: inGoogle);

/// A queue of lines of standard input.
final stdinLines = StreamQueue(lineSplitter.bind(stdin));

/// 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;

/// 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).deleteSync(recursive: true));
  });
}

/// 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>(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 {
  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['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;
  }
}
