// Copyright 2014 The Flutter 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';
import 'dart:math' as math;

import 'package:flutter_devicelab/common.dart';
import 'package:flutter_devicelab/framework/devices.dart';
import 'package:path/path.dart' as path;
import 'package:process/process.dart';
import 'package:stack_trace/stack_trace.dart';

import 'host_agent.dart';
import 'task_result.dart';

/// Virtual current working directory, which affect functions, such as [exec].
String cwd = Directory.current.path;

/// The local engine to use for [flutter] and [evalFlutter], if any.
String? get localEngine {
  // Use two distinct `defaultValue`s to determine whether a 'localEngine'
  // declaration exists in the environment.
  const bool isDefined =
      String.fromEnvironment('localEngine', defaultValue: 'a') ==
          String.fromEnvironment('localEngine', defaultValue: 'b');
  return isDefined ? const String.fromEnvironment('localEngine') : null;
}

/// The local engine source path to use if a local engine is used for [flutter]
/// and [evalFlutter].
String? get localEngineSrcPath {
  // Use two distinct `defaultValue`s to determine whether a
  // 'localEngineSrcPath' declaration exists in the environment.
  const bool isDefined =
      String.fromEnvironment('localEngineSrcPath', defaultValue: 'a') ==
          String.fromEnvironment('localEngineSrcPath', defaultValue: 'b');
  return isDefined ? const String.fromEnvironment('localEngineSrcPath') : null;
}

List<ProcessInfo> _runningProcesses = <ProcessInfo>[];
ProcessManager _processManager = const LocalProcessManager();

class ProcessInfo {
  ProcessInfo(this.command, this.process);

  final DateTime startTime = DateTime.now();
  final String command;
  final Process process;

  @override
  String toString() {
    return '''
  command : $command
  started : $startTime
  pid     : ${process.pid}
'''
        .trim();
  }
}

/// Result of a health check for a specific parameter.
class HealthCheckResult {
  HealthCheckResult.success([this.details]) : succeeded = true;
  HealthCheckResult.failure(this.details) : succeeded = false;
  HealthCheckResult.error(dynamic error, dynamic stackTrace)
      : succeeded = false,
        details = 'ERROR: $error${stackTrace != null ? '\n$stackTrace' : ''}';

  final bool succeeded;
  final String? details;

  @override
  String toString() {
    final StringBuffer buf = StringBuffer(succeeded ? 'succeeded' : 'failed');
    if (details != null && details!.trim().isNotEmpty) {
      buf.writeln();
      // Indent details by 4 spaces
      for (final String line in details!.trim().split('\n')) {
        buf.writeln('    $line');
      }
    }
    return '$buf';
  }
}

class BuildFailedError extends Error {
  BuildFailedError(this.message);

  final String message;

  @override
  String toString() => message;
}

void fail(String message) {
  throw BuildFailedError(message);
}

// Remove the given file or directory.
void rm(FileSystemEntity entity, { bool recursive = false}) {
  if (entity.existsSync()) {
    // This should not be necessary, but it turns out that
    // on Windows it's common for deletions to fail due to
    // bogus (we think) "access denied" errors.
    try {
      entity.deleteSync(recursive: recursive);
    } on FileSystemException catch (error) {
      print('Failed to delete ${entity.path}: $error');
    }
  }
}

/// Remove recursively.
void rmTree(FileSystemEntity entity) {
  rm(entity, recursive: true);
}

List<FileSystemEntity> ls(Directory directory) => directory.listSync();

Directory dir(String path) => Directory(path);

File file(String path) => File(path);

void copy(File sourceFile, Directory targetDirectory, {String? name}) {
  final File target = file(
      path.join(targetDirectory.path, name ?? path.basename(sourceFile.path)));
  target.writeAsBytesSync(sourceFile.readAsBytesSync());
}

void recursiveCopy(Directory source, Directory target) {
  if (!target.existsSync())
    target.createSync();

  for (final FileSystemEntity entity in source.listSync(followLinks: false)) {
    final String name = path.basename(entity.path);
    if (entity is Directory && !entity.path.contains('.dart_tool'))
      recursiveCopy(entity, Directory(path.join(target.path, name)));
    else if (entity is File) {
      final File dest = File(path.join(target.path, name));
      dest.writeAsBytesSync(entity.readAsBytesSync());
      // Preserve executable bit
      final String modes = entity.statSync().modeString();
      if (modes != null && modes.contains('x')) {
        makeExecutable(dest);
      }
    }
  }
}

FileSystemEntity move(FileSystemEntity whatToMove,
    {required Directory to, String? name}) {
  return whatToMove
      .renameSync(path.join(to.path, name ?? path.basename(whatToMove.path)));
}

/// Equivalent of `chmod a+x file`
void makeExecutable(File file) {
  // Windows files do not have an executable bit
  if (Platform.isWindows) {
    return;
  }
  final ProcessResult result = _processManager.runSync(<String>[
    'chmod',
    'a+x',
    file.path,
  ]);

  if (result.exitCode != 0) {
    throw FileSystemException(
      'Error making ${file.path} executable.\n'
      '${result.stderr}',
      file.path,
    );
  }
}

/// Equivalent of `mkdir directory`.
void mkdir(Directory directory) {
  directory.createSync();
}

/// Equivalent of `mkdir -p directory`.
void mkdirs(Directory directory) {
  directory.createSync(recursive: true);
}

bool exists(FileSystemEntity entity) => entity.existsSync();

void section(String title) {
  String output;
  if (Platform.isWindows) {
    // Windows doesn't cope well with characters produced for *nix systems, so
    // just output the title with no decoration.
    output = title;
  } else {
    title = '╡ ••• $title ••• ╞';
    final String line = '═' * math.max((80 - title.length) ~/ 2, 2);
    output = '$line$title$line';
    if (output.length == 79)
      output += '═';
  }
  print('\n\n$output\n');
}

Future<String> getDartVersion() async {
  // The Dart VM returns the version text to stderr.
  final ProcessResult result = _processManager.runSync(<String>[dartBin, '--version']);
  String version = (result.stderr as String).trim();

  // Convert:
  //   Dart VM version: 1.17.0-dev.2.0 (Tue May  3 12:14:52 2016) on "macos_x64"
  // to:
  //   1.17.0-dev.2.0
  if (version.contains('('))
    version = version.substring(0, version.indexOf('(')).trim();
  if (version.contains(':'))
    version = version.substring(version.indexOf(':') + 1).trim();

  return version.replaceAll('"', "'");
}

Future<String?> getCurrentFlutterRepoCommit() {
  if (!dir('${flutterDirectory.path}/.git').existsSync()) {
    return Future<String?>.value(null);
  }

  return inDirectory<String>(flutterDirectory, () {
    return eval('git', <String>['rev-parse', 'HEAD']);
  });
}

Future<DateTime> getFlutterRepoCommitTimestamp(String commit) {
  // git show -s --format=%at 4b546df7f0b3858aaaa56c4079e5be1ba91fbb65
  return inDirectory<DateTime>(flutterDirectory, () async {
    final String unixTimestamp = await eval('git', <String>[
      'show',
      '-s',
      '--format=%at',
      commit,
    ]);
    final int secondsSinceEpoch = int.parse(unixTimestamp);
    return DateTime.fromMillisecondsSinceEpoch(secondsSinceEpoch * 1000);
  });
}

/// Starts a subprocess.
///
/// The first argument is the full path to the executable to run.
///
/// The second argument is the list of arguments to provide on the command line.
/// This argument can be null, indicating no arguments (same as the empty list).
///
/// The `environment` argument can be provided to configure environment variables
/// that will be made available to the subprocess. The `BOT` environment variable
/// is always set and overrides any value provided in the `environment` argument.
/// The `isBot` argument controls the value of the `BOT` variable. It will either
/// be "true", if `isBot` is true (the default), or "false" if it is false.
///
/// The `BOT` variable is in particular used by the `flutter` tool to determine
/// how verbose to be and whether to enable analytics by default.
///
/// The working directory can be provided using the `workingDirectory` argument.
/// By default it will default to the current working directory (see [cwd]).
///
/// Information regarding the execution of the subprocess is printed to the
/// console.
///
/// The actual process executes asynchronously. A handle to the subprocess is
/// returned in the form of a [Future] that completes to a [Process] object.
Future<Process> startProcess(
  String executable,
  List<String>? arguments, {
  Map<String, String>? environment,
  bool isBot = true, // set to false to pretend not to be on a bot (e.g. to test user-facing outputs)
  String? workingDirectory,
}) async {
  assert(isBot != null);
  final String command = '$executable ${arguments?.join(" ") ?? ""}';
  final String finalWorkingDirectory = workingDirectory ?? cwd;
  final Map<String, String> newEnvironment = Map<String, String>.from(environment ?? <String, String>{});
  newEnvironment['BOT'] = isBot ? 'true' : 'false';
  newEnvironment['LANG'] = 'en_US.UTF-8';
  print('\nExecuting: $command in $finalWorkingDirectory with environment $newEnvironment');
  final Process process = await _processManager.start(
    <String>[executable, ...?arguments],
    environment: newEnvironment,
    workingDirectory: finalWorkingDirectory,
  );
  final ProcessInfo processInfo = ProcessInfo(command, process);
  _runningProcesses.add(processInfo);

  unawaited(process.exitCode.then<void>((int exitCode) {
    print('"$executable" exit code: $exitCode');
    _runningProcesses.remove(processInfo);
  }));

  return process;
}

Future<void> forceQuitRunningProcesses() async {
  if (_runningProcesses.isEmpty)
    return;

  // Give normally quitting processes a chance to report their exit code.
  await Future<void>.delayed(const Duration(seconds: 1));

  // Whatever's left, kill it.
  for (final ProcessInfo p in _runningProcesses) {
    print('Force-quitting process:\n$p');
    if (!p.process.kill()) {
      print('Failed to force quit process');
    }
  }
  _runningProcesses.clear();
}

/// Executes a command and returns its exit code.
Future<int> exec(
  String executable,
  List<String> arguments, {
  Map<String, String>? environment,
  bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
  String? workingDirectory,
}) async {
  return _execute(
    executable,
    arguments,
    environment: environment,
    canFail : canFail,
    workingDirectory: workingDirectory,
  );
}

Future<int> _execute(
  String executable,
  List<String> arguments, {
  Map<String, String>? environment,
  bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
  String? workingDirectory,
  StringBuffer? output, // if not null, the stdout will be written here
  StringBuffer? stderr, // if not null, the stderr will be written here
  bool printStdout = true,
  bool printStderr = true,
}) async {
  final Process process = await startProcess(
    executable,
    arguments,
    environment: environment,
    workingDirectory: workingDirectory,
  );
  await forwardStandardStreams(
    process,
    output: output,
    stderr: stderr,
    printStdout: printStdout,
    printStderr: printStderr,
    );
  final int exitCode = await process.exitCode;

  if (exitCode != 0 && !canFail)
    fail('Executable "$executable" failed with exit code $exitCode.');

  return exitCode;
}

/// Forwards standard out and standard error from [process] to this process'
/// respective outputs. Also writes stdout to [output] and stderr to [stderr]
/// if they are not null.
///
/// Returns a future that completes when both out and error streams a closed.
Future<void> forwardStandardStreams(
  Process process, {
  StringBuffer? output,
  StringBuffer? stderr,
  bool printStdout = true,
  bool printStderr = true,
  }) {
  final Completer<void> stdoutDone = Completer<void>();
  final Completer<void> stderrDone = Completer<void>();
  process.stdout
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen((String line) {
        if (printStdout) {
          print('stdout: $line');
        }
        output?.writeln(line);
      }, onDone: () { stdoutDone.complete(); });
  process.stderr
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen((String line) {
        if (printStderr) {
          print('stderr: $line');
        }
        stderr?.writeln(line);
      }, onDone: () { stderrDone.complete(); });

  return Future.wait<void>(<Future<void>>[
    stdoutDone.future,
    stderrDone.future,
  ]);
}

/// Executes a command and returns its standard output as a String.
///
/// For logging purposes, the command's output is also printed out by default.
Future<String> eval(
  String executable,
  List<String> arguments, {
  Map<String, String>? environment,
  bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
  String? workingDirectory,
  StringBuffer? stderr, // if not null, the stderr will be written here
  bool printStdout = true,
  bool printStderr = true,
}) async {
  final StringBuffer output = StringBuffer();
  await _execute(
    executable,
    arguments,
    environment: environment,
    canFail: canFail,
    workingDirectory: workingDirectory,
    output: output,
    stderr: stderr,
    printStdout: printStdout,
    printStderr: printStderr,
  );
  return output.toString().trimRight();
}

List<String> flutterCommandArgs(String command, List<String> options) {
  // Commands support the --device-timeout flag.
  final Set<String> supportedDeviceTimeoutCommands = <String>{
    'attach',
    'devices',
    'drive',
    'install',
    'logs',
    'run',
    'screenshot',
  };
  return <String>[
    command,
    if (deviceOperatingSystem == DeviceOperatingSystem.ios && supportedDeviceTimeoutCommands.contains(command))
      ...<String>[
        '--device-timeout',
        '5',
      ],

    if (command == 'drive' && hostAgent.dumpDirectory != null) ...<String>[
      '--screenshot',
      hostAgent.dumpDirectory!.path,
    ],
    if (localEngine != null) ...<String>['--local-engine', localEngine!],
    if (localEngineSrcPath != null) ...<String>['--local-engine-src-path', localEngineSrcPath!],
    ...options,
  ];
}

/// Runs the flutter `command`, and returns the exit code.
/// If `canFail` is `false`, the future completes with an error.
Future<int> flutter(String command, {
  List<String> options = const <String>[],
  bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
  Map<String, String>? environment,
}) {
  final List<String> args = flutterCommandArgs(command, options);
  return exec(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
    canFail: canFail, environment: environment);
}

Future<Process> startFlutter(String command, {
  List<String> options = const <String>[],
  Map<String, String> environment = const <String, String>{},
}) {
  final List<String> args = flutterCommandArgs(command, options);
  return startProcess(
    path.join(flutterDirectory.path, 'bin', 'flutter'),
    args,
    environment: environment,
  );
}

/// Runs a `flutter` command and returns the standard output as a string.
Future<String> evalFlutter(String command, {
  List<String> options = const <String>[],
  bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
  Map<String, String>? environment,
  StringBuffer? stderr, // if not null, the stderr will be written here.
}) {
  final List<String> args = flutterCommandArgs(command, options);
  return eval(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
      canFail: canFail, environment: environment, stderr: stderr);
}

Future<ProcessResult> executeFlutter(String command, {
  List<String> options = const <String>[],
}) async {
  final List<String> args = flutterCommandArgs(command, options);
  return _processManager.run(
    <String>[path.join(flutterDirectory.path, 'bin', 'flutter'), ...args],
    workingDirectory: cwd,
  );
}

String get dartBin =>
    path.join(flutterDirectory.path, 'bin', 'cache', 'dart-sdk', 'bin', 'dart');

String get pubBin =>
    path.join(flutterDirectory.path, 'bin', 'cache', 'dart-sdk', 'bin', 'pub');

Future<int> dart(List<String> args) => exec(dartBin, <String>['--disable-dart-dev', ...args]);

/// Returns a future that completes with a path suitable for JAVA_HOME
/// or with null, if Java cannot be found.
Future<String?> findJavaHome() async {
  if (_javaHome == null) {
    final Iterable<String> hits = grep(
      'Java binary at: ',
      from: await evalFlutter('doctor', options: <String>['-v']),
    );
    if (hits.isEmpty)
      return null;
    final String javaBinary = hits.first
        .split(': ')
        .last;
    // javaBinary == /some/path/to/java/home/bin/java
    _javaHome = path.dirname(path.dirname(javaBinary));
  }
  return _javaHome;
}
String? _javaHome;

Future<T> inDirectory<T>(dynamic directory, Future<T> Function() action) async {
  final String previousCwd = cwd;
  try {
    cd(directory);
    return await action();
  } finally {
    cd(previousCwd);
  }
}

void cd(dynamic directory) {
  Directory d;
  if (directory is String) {
    cwd = directory;
    d = dir(directory);
  } else if (directory is Directory) {
    cwd = directory.path;
    d = directory;
  } else {
    throw FileSystemException('Unsupported directory type ${directory.runtimeType}', directory.toString());
  }

  if (!d.existsSync())
    throw FileSystemException('Cannot cd into directory that does not exist', d.toString());
}

Directory get flutterDirectory => Directory.current.parent.parent;

String requireEnvVar(String name) {
  final String? value = Platform.environment[name];

  if (value == null)
    fail('$name environment variable is missing. Quitting.');

  return value!;
}

T requireConfigProperty<T>(Map<String, dynamic> map, String propertyName) {
  if (!map.containsKey(propertyName))
    fail('Configuration property not found: $propertyName');
  final T result = map[propertyName] as T;
  return result;
}

String jsonEncode(dynamic data) {
  final String jsonValue = const JsonEncoder.withIndent('  ').convert(data);
  return '$jsonValue\n';
}

Future<void> getNewGallery(String revision, Directory galleryDir) async {
  section('Get New Flutter Gallery!');

  if (exists(galleryDir)) {
    galleryDir.deleteSync(recursive: true);
  }

  await inDirectory<void>(galleryDir.parent, () async {
    await exec('git', <String>['clone', 'https://github.com/flutter/gallery.git']);
  });

  await inDirectory<void>(galleryDir, () async {
    await exec('git', <String>['checkout', revision]);
  });
}

void checkNotNull(Object o1,
    [Object o2 = 1,
    Object o3 = 1,
    Object o4 = 1,
    Object o5 = 1,
    Object o6 = 1,
    Object o7 = 1,
    Object o8 = 1,
    Object o9 = 1,
    Object o10 = 1]) {
  if (o1 == null)
    throw 'o1 is null';
  if (o2 == null)
    throw 'o2 is null';
  if (o3 == null)
    throw 'o3 is null';
  if (o4 == null)
    throw 'o4 is null';
  if (o5 == null)
    throw 'o5 is null';
  if (o6 == null)
    throw 'o6 is null';
  if (o7 == null)
    throw 'o7 is null';
  if (o8 == null)
    throw 'o8 is null';
  if (o9 == null)
    throw 'o9 is null';
  if (o10 == null)
    throw 'o10 is null';
}

/// Splits [from] into lines and selects those that contain [pattern].
Iterable<String> grep(Pattern pattern, {required String from}) {
  return from.split('\n').where((String line) {
    return line.contains(pattern);
  });
}

/// Captures asynchronous stack traces thrown by [callback].
///
/// This is a convenience wrapper around [Chain] optimized for use with
/// `async`/`await`.
///
/// Example:
///
///     try {
///       await captureAsyncStacks(() { /* async things */ });
///     } catch (error, chain) {
///
///     }
Future<void> runAndCaptureAsyncStacks(Future<void> Function() callback) {
  final Completer<void> completer = Completer<void>();
  Chain.capture(() async {
    await callback();
    completer.complete();
  }, onError: completer.completeError);
  return completer.future;
}

bool canRun(String path) => _processManager.canRun(path);

final RegExp _obsRegExp =
  RegExp('An Observatory debugger .* is available at: ');
final RegExp _obsPortRegExp = RegExp(r'(\S+:(\d+)/\S*)$');
final RegExp _obsUriRegExp = RegExp(r'((http|//)[a-zA-Z0-9:/=_\-\.\[\]]+)');

/// Tries to extract a port from the string.
///
/// The `prefix`, if specified, is a regular expression pattern and must not contain groups.
/// `prefix` defaults to the RegExp: `An Observatory debugger .* is available at: `.
int? parseServicePort(String line, {
  Pattern? prefix,
}) {
  prefix ??= _obsRegExp;
  final Iterable<Match> matchesIter = prefix.allMatches(line);
  if (matchesIter.isEmpty) {
    return null;
  }
  final Match prefixMatch = matchesIter.first;
  final List<Match> matches =
    _obsPortRegExp.allMatches(line, prefixMatch.end).toList();
  return matches.isEmpty ? null : int.parse(matches[0].group(2)!);
}

/// Tries to extract a URL from the string.
///
/// The `prefix`, if specified, is a regular expression pattern and must not contain groups.
/// `prefix` defaults to the RegExp: `An Observatory debugger .* is available at: `.
Uri? parseServiceUri(String line, {
  Pattern? prefix,
}) {
  prefix ??= _obsRegExp;
  final Iterable<Match> matchesIter = prefix.allMatches(line);
  if (matchesIter.isEmpty) {
    return null;
  }
  final Match prefixMatch = matchesIter.first;
  final List<Match> matches =
    _obsUriRegExp.allMatches(line, prefixMatch.end).toList();
  return matches.isEmpty ? null : Uri.parse(matches[0].group(0)!);
}

/// Checks that the file exists, otherwise throws a [FileSystemException].
void checkFileExists(String file) {
  if (!exists(File(file))) {
    throw FileSystemException('Expected file to exist.', file);
  }
}

/// Checks that the file does not exists, otherwise throws a [FileSystemException].
void checkFileNotExists(String file) {
  if (exists(File(file))) {
    throw FileSystemException('Expected file to not exist.', file);
  }
}

/// Checks that the directory exists, otherwise throws a [FileSystemException].
void checkDirectoryExists(String directory) {
  if (!exists(Directory(directory))) {
    throw FileSystemException('Expected directory to exist.', directory);
  }
}

/// Checks that the directory does not exist, otherwise throws a [FileSystemException].
void checkDirectoryNotExists(String directory) {
  if (exists(Directory(directory))) {
    throw FileSystemException('Expected directory to not exist.', directory);
  }
}

/// Check that `collection` contains all entries in `values`.
void checkCollectionContains<T>(Iterable<T> values, Iterable<T> collection) {
  for (final T value in values) {
    if (!collection.contains(value)) {
      throw TaskResult.failure('Expected to find `$value` in `${collection.toString()}`.');
    }
  }
}

/// Check that `collection` does not contain any entries in `values`
void checkCollectionDoesNotContain<T>(Iterable<T> values, Iterable<T> collection) {
  for (final T value in values) {
    if (collection.contains(value)) {
      throw TaskResult.failure('Did not expect to find `$value` in `$collection`.');
    }
  }
}

/// Checks that the contents of a [File] at `filePath` contains the specified
/// [Pattern]s, otherwise throws a [TaskResult].
void checkFileContains(List<Pattern> patterns, String filePath) {
  final String fileContent = File(filePath).readAsStringSync();
  for (final Pattern pattern in patterns) {
    if (!fileContent.contains(pattern)) {
      throw TaskResult.failure(
        'Expected to find `$pattern` in `$filePath` '
        'instead it found:\n$fileContent'
      );
    }
  }
}

/// Clones a git repository.
///
/// Removes the directory [path], then clones the git repository
/// specified by [repo] to the directory [path].
Future<int> gitClone({required String path, required String repo}) async {
  rmTree(Directory(path));

  await Directory(path).create(recursive: true);

  return inDirectory<int>(
    path,
        () => exec('git', <String>['clone', repo]),
  );
}

/// Call [fn] retrying so long as [retryIf] return `true` for the exception
/// thrown and [maxAttempts] has not been reached.
///
/// If no [retryIf] function is given this will retry any for any [Exception]
/// thrown. To retry on an [Error], the error must be caught and _rethrown_
/// as an [Exception].
///
/// Waits a constant duration of [delayDuration] between every retry attempt.
Future<T> retry<T>(
  FutureOr<T> Function() fn, {
  FutureOr<bool> Function(Exception)? retryIf,
  int maxAttempts = 5,
  Duration delayDuration = const Duration(seconds: 3),
}) async {
  int attempt = 0;
  while (true) {
    attempt++; // first invocation is the first attempt
    try {
      return await fn();
    } on Exception catch (e) {
      if (attempt >= maxAttempts ||
          (retryIf != null && !(await retryIf(e)))) {
        rethrow;
      }
    }

    // Sleep for a delay
    await Future<void>.delayed(delayDuration);
  }
}
