// Copyright (c) 2020, 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:io';
import 'dart:isolate';

import 'package:cli_util/cli_logging.dart';
import 'package:dartdev/dartdev.dart';
import 'package:dartdev/src/core.dart';
import 'package:file/memory.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';
import 'package:unified_analytics/unified_analytics.dart';

/// A long [Timeout] is provided for tests that start a process on
/// `bin/dartdev.dart` as the command is not compiled ahead of time, and each
/// invocation requires the VM to compile the entire dependency graph.
const Timeout longTimeout = Timeout(Duration(minutes: 5));

/// This version of dart is the last guaranteed pre-null safety language
/// version:
const String dartVersionFilePrefix2_9 = '''
// ignore: illegal_language_version_override
// @dart = 2.9
''';

const residentFrontendCompilerPrefix =
    'The Resident Frontend Compiler is listening at 127.0.0.1:';

/// Return the root URI of the SDK by walking up from the pkg/dartdev folder.
final sdkRootUri = resolveDartDevUri('../../');

void initGlobalState() {
  log = Logger.standard();
}

/// Creates a test-project in a temp-dir that will [dispose] itself at the end
/// of the test.
TestProject project({
  String? mainSrc,
  String? analysisOptions,
  String name = TestProject._defaultProjectName,
  VersionConstraint? sdkConstraint,
  Map<String, dynamic>? pubspecExtras,
}) {
  var testProject = TestProject(
    mainSrc: mainSrc,
    name: name,
    analysisOptions: analysisOptions,
    sdkConstraint: sdkConstraint,
    pubspecExtras: pubspecExtras,
  );
  addTearDown(() => testProject.dispose());
  return testProject;
}

class TestProject {
  static const String _defaultProjectName = 'dartdev_temp';

  late Directory root;

  Directory get dir => Directory(dirPath);

  String get dirPath => path.join(root.path, 'myapp');

  String get pubCachePath => path.join(root.path, 'pub_cache');

  String get pubCacheBinPath => path.join(pubCachePath, 'bin');

  String get mainPath => path.join(dirPath, relativeFilePath);

  String get analysisOptionsPath => path.join(dirPath, 'analysis_options.yaml');

  String get packageConfigPath =>
      path.join(dirPath, '.dart_tool', 'package_config.json');

  final String name;

  String get relativeFilePath => 'lib/main.dart';

  Process? _process;

  TestProject({
    String? mainSrc,
    String? analysisOptions,
    this.name = _defaultProjectName,
    VersionConstraint? sdkConstraint,
    Map<String, dynamic>? pubspecExtras,
  }) {
    initGlobalState();
    root = Directory.systemTemp.createTempSync('dartdev');
    file(
      'pubspec.yaml',
      JsonEncoder.withIndent('  ').convert({
        'name': name,
        'environment': {'sdk': sdkConstraint?.toString() ?? '^3.0.0'},
        ...?pubspecExtras,
      }),
    );
    file(
      '.dart_tool/package_config.json',
      JsonEncoder.withIndent('  ').convert({
        'configVersion': 2,
        'generator': 'utils.dart',
        'packages': [
          {
            'name': name,
            'rootUri': '../',
            'packageUri': 'lib/',
            'languageVersion': '3.2',
          },
        ],
      }),
    );
    file(
      '.dart_tool/package_graph.json',
      JsonEncoder.withIndent('  ').convert({
        'roots': [name],
        'packages': [
          {
            'name': name,
            'version': '1.0.0',
            'dependencies': [],
            'devDependencies': [],
          },
        ],
        'configVersion': 1,
      }),
    );
    if (analysisOptions != null) {
      file('analysis_options.yaml', analysisOptions);
    }
    if (mainSrc != null) {
      file(relativeFilePath, mainSrc);
    }
  }

  void file(String name, String contents) {
    var file = File(path.join(dir.path, name));
    file.parent.createSync(recursive: true);
    file.writeAsStringSync(contents);
  }

  void deleteFile(String name) {
    var file = File(path.join(dir.path, name));
    assert(file.existsSync());
    file.deleteSync();
  }

  Future<void> dispose() async {
    _process?.kill();
    await _process?.exitCode;
    _process = null;
    await deleteDirectory(root);
  }

  Future<void> kill() async {
    _process?.kill();
    _process = null;
  }

  Future<ProcessResult> runAnalyze(
    List<String> arguments, {
    String? workingDir,
  }) async {
    return run(['analyze', '--suppress-analytics', ...arguments]);
  }

  Future<ProcessResult> runFix(
    List<String> arguments, {
    String? workingDir,
  }) async {
    return run(['fix', '--suppress-analytics', ...arguments]);
  }

  Future<ProcessResult> run(
    List<String> arguments, {
    String? workingDir,
  }) async {
    final process = await start(arguments, workingDir: workingDir);
    final stdoutContents = process.stdout.transform(utf8.decoder).join();
    final stderrContents = process.stderr.transform(utf8.decoder).join();
    final code = await process.exitCode;
    return ProcessResult(
      process.pid,
      code,
      await stdoutContents,
      await stderrContents,
    );
  }

  Future<Process> start(List<String> arguments, {String? workingDir}) {
    return Process.start(
      Platform.resolvedExecutable,
      [...arguments],
      workingDirectory: workingDir ?? dir.path,
      environment: {'PUB_CACHE': pubCachePath},
    )..then((p) => _process = p);
  }

  Future<void> runWithVmService(
    List<String> arguments,
    void Function(String) onStdout, {
    String? workingDir,
  }) async {
    final process = await start(arguments, workingDir: workingDir);
    final completer = Completer<void>();
    late StreamSubscription<String> sub;
    late StreamSubscription<String> subError;

    void onData(event) {
      print('stdout: $event');
      onStdout(event);
    }

    void onStderr(event) async {
      print('stderr: $event');
      if (event.contains(residentFrontendCompilerPrefix)) {
        onStdout(event);
        return;
      }
      await subError.cancel();
      await sub.cancel();
      completer.complete();
      fail('stderr is expected to be empty, but got: $event');
    }

    void onError(error) async {
      kill();
      await subError.cancel();
      await sub.cancel();
      completer.complete();
    }

    void onDone() async {
      await subError.cancel();
      await sub.cancel();
      completer.complete();
    }

    sub = process.stdout
        .transform(utf8.decoder)
        .transform(const LineSplitter())
        .listen(onData, onError: onError, onDone: onDone);
    subError = process.stderr.transform(utf8.decoder).listen(onStderr);

    // Wait for process to start and run.
    await completer.future;
  }

  Future<FakeAnalytics> runLocalWithFakeAnalytics(
    List<String> arguments, {
    String? workingDir,
  }) async {
    final analytics = _createFakeAnalytics();

    final originalDir = Directory.current;
    Directory.current = dir;

    final runner = DartdevRunner(arguments, analyticsOverride: analytics);
    await runner.runCommand(runner.parse(arguments));

    Directory.current = originalDir;
    return analytics;
  }

  FakeAnalytics _createFakeAnalytics() {
    final fs = MemoryFileSystem.test(style: FileSystemStyle.posix);
    final homeDirectory = fs.directory('/');
    final FakeAnalytics initialAnalytics = Analytics.fake(
      tool: DashTool.dartTool,
      homeDirectory: homeDirectory,
      dartVersion: 'dartVersion',
      fs: fs,
    );
    initialAnalytics.clientShowedMessage();

    return Analytics.fake(
      tool: DashTool.dartTool,
      homeDirectory: homeDirectory,
      dartVersion: 'dartVersion',
      fs: fs,
    );
  }

  String get absolutePathToDartdevFile =>
      sdkRootUri.resolve('pkg/dartdev/bin/dartdev.dart').toFilePath();

  Directory? findDirectory(String name) {
    var directory = Directory(path.join(dir.path, name));
    return directory.existsSync() ? directory : null;
  }

  File? findFile(String name) {
    var file = File(path.join(dir.path, name));
    return file.existsSync() ? file : null;
  }
}

/// Deletes [dir] with some retries to reduce the chances of file locking errors
/// on Windows where files may fail to delete for a short period after the
/// process that locked them terminates.
Future<void> deleteDirectory(Directory dir) async {
  int deleteAttempts = 5;
  while (deleteAttempts >= 0) {
    deleteAttempts--;
    try {
      if (!dir.existsSync()) {
        return;
      }
      dir.deleteSync(recursive: true);
    } catch (e) {
      if (deleteAttempts <= 0) {
        rethrow;
      }
      await Future.delayed(Duration(milliseconds: 500));
      log.stdout('Got $e while deleting $dir. Trying again...');
    }
  }
}

/// Checks that this is the `dart` executable in the bin folder rather than the
/// `dart` in the root of the build folder.
///
/// Many of this package tests rely on having the SDK folder layout.
void ensureRunFromSdkBinDart() {
  final uri = Uri.file(Platform.resolvedExecutable);
  final pathReversed = uri.pathSegments.reversed.toList();
  if (!pathReversed[0].startsWith('dart')) {
    throw StateError('Main executable is not Dart: ${uri.toFilePath()}.');
  }
  if (pathReversed.length < 2 || pathReversed[1] != 'bin') {
    throw StateError(
      '''Main executable is not from an SDK build: ${uri.toFilePath()}.
The `pkg/dartdev` tests must be run with the `dart` executable in the `bin` folder.
''',
    );
  }
}

/// Replaces the path [filePath] case-insensitively in [input] with itself.
///
/// This allows comparing strings that contain file paths where the casing may
/// be different but is not important to the test (for example where a drive
/// letter might have different casing).
String replacePathsWithMatchingCase(String input, {required String filePath}) {
  return input.replaceAll(
    RegExp(RegExp.escape(filePath), caseSensitive: false),
    filePath,
  );
}

/// Resolves a relative URI from the pkg/dartdev folder.
Uri resolveDartDevUri(String path) {
  final dartDevLibUri = Isolate.resolvePackageUriSync(
    Uri.parse('package:dartdev/'),
  );
  return dartDevLibUri!.resolve('../$path');
}
