// Copyright (c) 2021, 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 'package:dds/src/dap/logging.dart';
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import 'test_client.dart';
import 'test_server.dart';

/// A [RegExp] that matches the "Connecting to VM Service" banner that is sent
/// by the DAP adapter as the first output event for a debug session.
final dapVmServiceBannerPattern =
    RegExp(r'Connecting to VM Service at ([^\s]+)\s');

/// Whether to run the DAP server in-process with the tests, or externally in
/// another process.
///
/// By default tests will run the DAP server out-of-process to match the real
/// use from editors, but this complicates debugging the adapter. Set this env
/// variables to run the server in-process for easier debugging (this can be
/// simplified in VS Code by using a launch config with custom CodeLens links).
final useInProcessDap = Platform.environment['DAP_TEST_INTERNAL'] == 'true';

/// Whether to print all protocol traffic to stdout while running tests.
///
/// This is useful for debugging locally or on the bots and will include both
/// DAP traffic (between the test DAP client and the DAP server) and the VM
/// Service traffic (wrapped in a custom 'dart.log' event).
final verboseLogging = Platform.environment['DAP_TEST_VERBOSE'] == 'true';

/// A [RegExp] that matches the `path` part of a VM Service URI that contains
/// an authentication token.
final vmServiceAuthCodePathPattern = RegExp(r'^/[\w_\-=]{5,15}/ws$');

/// A [RegExp] that matches the "Observatory listening on" banner that is sent
/// by the VM when not using --write-service-info.
final vmServiceBannerPattern = RegExp(r'Observatory listening on ([^\s]+)\s');

/// Expects [actual] to equal the lines [expected], ignoring differences in line
/// endings and trailing whitespace.
void expectLines(String actual, List<String> expected) {
  expect(
    actual.replaceAll('\r\n', '\n').trim(),
    equals(expected.join('\n').trim()),
  );
}

/// Expects [actual] starts with [expected], ignoring differences in line
/// endings and trailing whitespace.
void expectLinesStartWith(String actual, List<String> expected) {
  expect(
    actual.replaceAll('\r\n', '\n').trim(),
    startsWith(expected.join('\n').trim()),
  );
}

/// Expects [response] to fail with a `message` matching [messageMatcher].
expectResponseError<T>(Future<T> response, Matcher messageMatcher) {
  expect(
    response,
    throwsA(
      const TypeMatcher<Response>()
          .having((r) => r.success, 'success', isFalse)
          .having((r) => r.message, 'message', messageMatcher),
    ),
  );
}

/// Returns the 1-base line in [file] that contains [searchText].
int lineWith(File file, String searchText) =>
    file.readAsLinesSync().indexWhere((line) => line.contains(searchText)) + 1;

Future<Process> startDartProcessPaused(
  String script,
  List<String> args, {
  required String cwd,
  List<String>? vmArgs,
}) async {
  final vmPath = Platform.resolvedExecutable;
  vmArgs ??= [];
  vmArgs.addAll([
    '--enable-vm-service=0',
    '--pause_isolates_on_start=true',
  ]);
  final processArgs = [
    ...vmArgs,
    script,
    ...args,
  ];

  return Process.start(
    vmPath,
    processArgs,
    workingDirectory: cwd,
  );
}

/// Monitors [process] for the Observatory/VM Service banner and extracts the
/// VM Service URI.
Future<Uri> waitForStdoutVmServiceBanner(Process process) {
  final _vmServiceUriCompleter = Completer<Uri>();

  late StreamSubscription<String> vmServiceBannerSub;
  vmServiceBannerSub = process.stdout.transform(utf8.decoder).listen(
    (line) {
      final match = vmServiceBannerPattern.firstMatch(line);
      if (match != null) {
        _vmServiceUriCompleter.complete(Uri.parse(match.group(1)!));
        vmServiceBannerSub.cancel();
      }
    },
    onDone: () {
      if (!_vmServiceUriCompleter.isCompleted) {
        _vmServiceUriCompleter.completeError('Stream ended');
      }
    },
  );

  return _vmServiceUriCompleter.future;
}

/// A helper class containing the DAP server/client for DAP integration tests.
class DapTestSession {
  DapTestServer server;
  DapTestClient client;
  final Directory _testDir =
      Directory.systemTemp.createTempSync('dart-sdk-dap-test');
  late final Directory testAppDir;
  late final Directory testPackageDir;
  var _packageConfig = PackageConfig.empty;

  DapTestSession._(this.server, this.client) {
    testAppDir = _testDir.createTempSync('app');
    testPackageDir = _testDir.createTempSync('packages');
  }

  /// Create a simple package named `foo` that has an empty `foo` function.
  Future<Uri> createFooPackage() {
    return createSimplePackage(
      'foo',
      '''
foo() {
  // Does nothing.
}
      ''',
    );
  }

  /// Creates a simple package script and adds the package to
  /// .dart_tool/package_config.json
  Future<Uri> createSimplePackage(
    String name,
    String content,
  ) async {
    final dartToolDirectory =
        Directory(path.join(testAppDir.path, '.dart_tool'))..createSync();
    final packageConfigJsonFile =
        File(path.join(dartToolDirectory.path, 'package_config.json'));
    final packageConfigJsonUri = Uri.file(packageConfigJsonFile.path);

    // Write the packages Dart implementation file.
    final testPackageDirectory = Directory(path.join(testPackageDir.path, name))
      ..createSync(recursive: true);
    final testFile = File(path.join(testPackageDirectory.path, '$name.dart'));
    testFile.writeAsStringSync(content);

    // Add this new package to the PackageConfig.
    final newPackage = Package(name, Uri.file('${testPackageDirectory.path}/'));
    _packageConfig = PackageConfig([..._packageConfig.packages, newPackage]);

    // Write the PackageConfig to disk.
    final sink = packageConfigJsonFile.openWrite();
    PackageConfig.writeString(_packageConfig, sink, packageConfigJsonUri);
    await sink.close();

    return Uri.parse('package:$name/$name.dart');
  }

  /// Creates a file in a temporary folder to be used as an application for testing.
  ///
  /// The file will be deleted at the end of the test run.
  File createTestFile(String content) {
    final testFile = File(path.join(testAppDir.path, 'test_file.dart'));
    testFile.writeAsStringSync(content);
    return testFile;
  }

  Future<void> tearDown() async {
    await client.stop();
    await server.stop();

    // Clean up any temp folders created during the test runs.
    _testDir.deleteSync(recursive: true);
  }

  static Future<DapTestSession> setUp({List<String>? additionalArgs}) async {
    final server = await _startServer(additionalArgs: additionalArgs);
    final client = await DapTestClient.connect(
      server,
      captureVmServiceTraffic: verboseLogging,
      logger: verboseLogging ? print : null,
    );
    return DapTestSession._(server, client);
  }

  /// Starts a DAP server that can be shared across tests.
  static Future<DapTestServer> _startServer({
    Logger? logger,
    List<String>? additionalArgs,
  }) async {
    return useInProcessDap
        ? await InProcessDapTestServer.create(
            logger: logger,
            additionalArgs: additionalArgs,
          )
        : await OutOfProcessDapTestServer.create(
            logger: logger,
            additionalArgs: additionalArgs,
          );
  }
}
