// Copyright (c) 2019, 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.

library test_helper;

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:vm_service/vm_service_io.dart';
import 'package:vm_service/vm_service.dart';
import 'package:test/test.dart';
import 'service_test_common.dart';
export 'service_test_common.dart' show IsolateTest, VMTest;

/// Whether to use causal async stacks (if not we use lazy async stacks).
const bool useCausalAsyncStacks =
    bool.fromEnvironment('dart.developer.causal_async_stacks');

/// The extra arguments to use
const List<String> extraDebuggingArgs = useCausalAsyncStacks
    ? ['--causal-async-stacks', '--no-lazy-async-stacks']
    : ['--no-causal-async-stacks', '--lazy-async-stacks'];

/// Will be set to the http address of the VM's service protocol before
/// any tests are invoked.
String serviceHttpAddress;
String serviceWebsocketAddress;

const String _TESTEE_ENV_KEY = 'SERVICE_TEST_TESTEE';
const Map<String, String> _TESTEE_SPAWN_ENV = {_TESTEE_ENV_KEY: 'true'};
bool _isTestee() {
  return Platform.environment.containsKey(_TESTEE_ENV_KEY);
}

Uri _getTestUri() {
  if (Platform.script.scheme == 'data') {
    // If we're using pub to run these tests this value isn't a file URI.
    // We'll need to parse the actual URI out...
    final fileRegExp = RegExp(r'file:\/\/\/.*\.dart');
    final path = fileRegExp.stringMatch(Platform.script.data.contentAsString());
    if (path == null) {
      throw 'Unable to determine file path for script!';
    }
    return Uri.parse(path);
  } else {
    return Platform.script;
  }
}

class _ServiceTesteeRunner {
  Future run(
      {Function() testeeBefore,
      Function() testeeConcurrent,
      bool pause_on_start = false,
      bool pause_on_exit = false}) async {
    if (!pause_on_start) {
      if (testeeBefore != null) {
        var result = testeeBefore();
        if (result is Future) {
          await result;
        }
      }
      print(''); // Print blank line to signal that testeeBefore has run.
    }
    if (testeeConcurrent != null) {
      var result = testeeConcurrent();
      if (result is Future) {
        await result;
      }
    }
    if (!pause_on_exit) {
      // Wait around for the process to be killed.
      // ignore: unawaited_futures
      stdin.first.then((_) => exit(0));
    }
  }

  void runSync(
      {void Function() testeeBeforeSync,
      void Function() testeeConcurrentSync,
      bool pause_on_start = false,
      bool pause_on_exit = false}) {
    if (!pause_on_start) {
      if (testeeBeforeSync != null) {
        testeeBeforeSync();
      }
      print(''); // Print blank line to signal that testeeBefore has run.
    }
    if (testeeConcurrentSync != null) {
      testeeConcurrentSync();
    }
    if (!pause_on_exit) {
      // Wait around for the process to be killed.
      stdin.first.then((_) => exit(0));
    }
  }
}

class _ServiceTesteeLauncher {
  Process process;
  List<String> args;
  bool killedByTester = false;

  _ServiceTesteeLauncher() : args = [_getTestUri().toFilePath()];

  // Spawn the testee process.
  Future<Process> _spawnProcess(
    bool pause_on_start,
    bool pause_on_exit,
    bool pause_on_unhandled_exceptions,
    bool testeeControlsServer,
    bool useAuthToken,
    List<String> extraArgs,
  ) {
    assert(pause_on_start != null);
    assert(pause_on_exit != null);
    assert(pause_on_unhandled_exceptions != null);
    assert(testeeControlsServer != null);
    assert(useAuthToken != null);
    return _spawnDartProcess(
        pause_on_start,
        pause_on_exit,
        pause_on_unhandled_exceptions,
        testeeControlsServer,
        useAuthToken,
        extraArgs);
  }

  Future<Process> _spawnDartProcess(
      bool pause_on_start,
      bool pause_on_exit,
      bool pause_on_unhandled_exceptions,
      bool testeeControlsServer,
      bool useAuthToken,
      List<String> extraArgs) {
    String dartExecutable = Platform.executable;

    var fullArgs = <String>[
      '--disable-dart-dev',
    ];
    if (pause_on_start) {
      fullArgs.add('--pause-isolates-on-start');
    }
    if (pause_on_exit) {
      fullArgs.add('--pause-isolates-on-exit');
    }
    if (!useAuthToken) {
      fullArgs.add('--disable-service-auth-codes');
    }
    if (pause_on_unhandled_exceptions) {
      fullArgs.add('--pause-isolates-on-unhandled-exceptions');
    }
    fullArgs.add('--profiler');
    if (extraArgs != null) {
      fullArgs.addAll(extraArgs);
    }

    fullArgs.addAll(Platform.executableArguments);
    if (!testeeControlsServer) {
      fullArgs.add('--enable-vm-service:0');
    }
    fullArgs.addAll(args);

    return _spawnCommon(dartExecutable, fullArgs, <String, String>{});
  }

  Future<Process> _spawnCommon(String executable, List<String> arguments,
      Map<String, String> dartEnvironment) {
    var environment = _TESTEE_SPAWN_ENV;
    var bashEnvironment = StringBuffer();
    environment.forEach((k, v) => bashEnvironment.write("$k=$v "));
    if (dartEnvironment != null) {
      dartEnvironment.forEach((k, v) {
        arguments.insert(0, '-D$k=$v');
      });
    }
    print('** Launching $bashEnvironment$executable ${arguments.join(' ')}');
    return Process.start(executable, arguments, environment: environment);
  }

  Future<Uri> launch(
      bool pause_on_start,
      bool pause_on_exit,
      bool pause_on_unhandled_exceptions,
      bool testeeControlsServer,
      bool useAuthToken,
      List<String> extraArgs) {
    return _spawnProcess(
            pause_on_start,
            pause_on_exit,
            pause_on_unhandled_exceptions,
            testeeControlsServer,
            useAuthToken,
            extraArgs)
        .then((p) {
      Completer<Uri> completer = Completer<Uri>();
      process = p;
      Uri uri;
      var blank;
      var first = true;
      process.stdout
          .transform(utf8.decoder)
          .transform(LineSplitter())
          .listen((line) {
        const kObservatoryListening = 'Observatory listening on ';
        if (line.startsWith(kObservatoryListening)) {
          uri = Uri.parse(line.substring(kObservatoryListening.length));
        }
        if (pause_on_start || line == '') {
          // Received blank line.
          blank = true;
        }
        if ((uri != null) && (blank == true) && (first == true)) {
          completer.complete(uri);
          // Stop repeat completions.
          first = false;
          print('** Signaled to run test queries on $uri');
        }
        stdout.write('>testee>out> ${line}\n');
      });
      process.stderr
          .transform(utf8.decoder)
          .transform(LineSplitter())
          .listen((line) {
        stdout.write('>testee>err> ${line}\n');
      });
      process.exitCode.then((exitCode) {
        if ((exitCode != 0) && !killedByTester) {
          throw "Testee exited with $exitCode";
        }
        print("** Process exited");
      });
      return completer.future;
    });
  }

  void requestExit() {
    if (process != null) {
      print('** Killing script');
      if (process.kill()) {
        killedByTester = true;
      }
    }
  }
}

void setupAddresses(Uri serverAddress) {
  serviceWebsocketAddress =
      'ws://${serverAddress.authority}${serverAddress.path}ws';
  serviceHttpAddress = 'http://${serverAddress.authority}${serverAddress.path}';
}

class _ServiceTesterRunner {
  Future run(
      {List<String> mainArgs,
      List<String> extraArgs,
      List<VMTest> vmTests,
      List<IsolateTest> isolateTests,
      bool pause_on_start = false,
      bool pause_on_exit = false,
      bool verbose_vm = false,
      bool pause_on_unhandled_exceptions = false,
      bool testeeControlsServer = false,
      bool useAuthToken = false}) async {
    var process = _ServiceTesteeLauncher();
    VmService vm;
    IsolateRef isolate;
    setUp(() async {
      await process
          .launch(pause_on_start, pause_on_exit, pause_on_unhandled_exceptions,
              testeeControlsServer, useAuthToken, extraArgs)
          .then((Uri serverAddress) async {
        if (mainArgs.contains("--gdb")) {
          var pid = process.process.pid;
          var wait = Duration(seconds: 10);
          print("Testee has pid $pid, waiting $wait before continuing");
          sleep(wait);
        }
        setupAddresses(serverAddress);
        vm = await vmServiceConnectUri(serviceWebsocketAddress);
        print('Done loading VM');
        isolate = await getFirstIsolate(vm);
      });
    });

    final name = _getTestUri().pathSegments.last;

    test(
      name,
      () async {
        // Run vm tests.
        if (vmTests != null) {
          var testIndex = 1;
          var totalTests = vmTests.length;
          for (var t in vmTests) {
            print('$name [$testIndex/$totalTests]');
            await t(vm);
            testIndex++;
          }
        }

        // Run isolate tests.
        if (isolateTests != null) {
          var testIndex = 1;
          var totalTests = isolateTests.length;
          for (var t in isolateTests) {
            print('$name [$testIndex/$totalTests]');
            await t(vm, isolate);
            testIndex++;
          }
        }
      },
      retry: 0,
      timeout: Timeout.none,
    );

    tearDown(() {
      print('All service tests completed successfully.');
      process.requestExit();
    });
  }

  Future<IsolateRef> getFirstIsolate(VmService service) async {
    var vm = await service.getVM();

    if (vm.isolates.isNotEmpty) {
      return vm.isolates.first;
    }
    var completer = Completer();
    StreamSubscription subscription;
    subscription = service.onIsolateEvent.listen((Event event) async {
      if (completer == null) {
        await subscription.cancel();
        return;
      }
      if (event.kind == EventKind.kIsolateRunnable) {
        vm = await service.getVM();
        assert(vm.isolates.isNotEmpty);
        await subscription.cancel();
        completer.complete(vm.isolates.first);
        completer = null;
      }
    });

    // The isolate may have started before we subscribed.
    vm = await service.getVM();
    if (vm.isolates.isNotEmpty) {
      await subscription.cancel();
      completer.complete(vm.isolates.first);
      completer = null;
    }
    return await completer.future;
  }
}

/// Runs [tests] in sequence, each of which should take an [Isolate] and
/// return a [Future]. Code for setting up state can run before and/or
/// concurrently with the tests. Uses [mainArgs] to determine whether
/// to run tests or testee in this invocation of the script.
Future<void> runIsolateTests(
  List<String> mainArgs,
  List<IsolateTest> tests, {
  testeeBefore(),
  testeeConcurrent(),
  bool pause_on_start = false,
  bool pause_on_exit = false,
  bool verbose_vm = false,
  bool pause_on_unhandled_exceptions = false,
  bool testeeControlsServer = false,
  bool useAuthToken = false,
  List<String> extraArgs,
}) async {
  assert(!pause_on_start || testeeBefore == null);
  if (_isTestee()) {
    await _ServiceTesteeRunner().run(
        testeeBefore: testeeBefore,
        testeeConcurrent: testeeConcurrent,
        pause_on_start: pause_on_start,
        pause_on_exit: pause_on_exit);
  } else {
    await _ServiceTesterRunner().run(
        mainArgs: mainArgs,
        extraArgs: extraArgs,
        isolateTests: tests,
        pause_on_start: pause_on_start,
        pause_on_exit: pause_on_exit,
        verbose_vm: verbose_vm,
        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions,
        testeeControlsServer: testeeControlsServer,
        useAuthToken: useAuthToken);
  }
}

/// Runs [tests] in sequence, each of which should take an [Isolate] and
/// return a [Future]. Code for setting up state can run before and/or
/// concurrently with the tests. Uses [mainArgs] to determine whether
/// to run tests or testee in this invocation of the script.
///
/// This is a special version of this test harness specifically for the
/// pause_on_unhandled_exceptions_test, which cannot properly function
/// in an async context (because exceptions are *always* handled in async
/// functions).
void runIsolateTestsSynchronous(
  List<String> mainArgs,
  List<IsolateTest> tests, {
  void testeeBefore(),
  void testeeConcurrent(),
  bool pause_on_start = false,
  bool pause_on_exit = false,
  bool verbose_vm = false,
  bool pause_on_unhandled_exceptions = false,
  List<String> extraArgs,
}) {
  assert(!pause_on_start || testeeBefore == null);
  if (_isTestee()) {
    _ServiceTesteeRunner().runSync(
        testeeBeforeSync: testeeBefore,
        testeeConcurrentSync: testeeConcurrent,
        pause_on_start: pause_on_start,
        pause_on_exit: pause_on_exit);
  } else {
    _ServiceTesterRunner().run(
        mainArgs: mainArgs,
        extraArgs: extraArgs,
        isolateTests: tests,
        pause_on_start: pause_on_start,
        pause_on_exit: pause_on_exit,
        verbose_vm: verbose_vm,
        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
  }
}

/// Runs [tests] in sequence, each of which should take an [Isolate] and
/// return a [Future]. Code for setting up state can run before and/or
/// concurrently with the tests. Uses [mainArgs] to determine whether
/// to run tests or testee in this invocation of the script.
Future<void> runVMTests(
  List<String> mainArgs,
  List<VMTest> tests, {
  testeeBefore(),
  testeeConcurrent(),
  bool pause_on_start = false,
  bool pause_on_exit = false,
  bool verbose_vm = false,
  bool pause_on_unhandled_exceptions = false,
  List<String> extraArgs,
}) async {
  if (_isTestee()) {
    await _ServiceTesteeRunner().run(
        testeeBefore: testeeBefore,
        testeeConcurrent: testeeConcurrent,
        pause_on_start: pause_on_start,
        pause_on_exit: pause_on_exit);
  } else {
    await _ServiceTesterRunner().run(
        mainArgs: mainArgs,
        extraArgs: extraArgs,
        vmTests: tests,
        pause_on_start: pause_on_start,
        pause_on_exit: pause_on_exit,
        verbose_vm: verbose_vm,
        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
  }
}
