// Copyright (c) 2016, 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.
// VMOptions=--error_on_bad_type --error_on_bad_override

import 'dart:async';
import 'dart:convert';
import 'package:observatory/service_io.dart';
import 'package:unittest/unittest.dart';
import 'service_test_common.dart';
import 'test_helper.dart';

var tests = [
  (VM vm) async {
    // Create a new fs.
    var fsName = 'scratch';
    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
        'fsName': fsName,
      });
    expect(result['type'], equals('FileSystem'));
    expect(result['name'], equals('scratch'));
    expect(result['uri'], new isInstanceOf<String>());
    var fsUri = result['uri'];

    // Spawn a script with a bad uri and make sure that the error is
    // delivered asynchronously.
    Completer completer = new Completer();
    var sub;
    sub = await vm.listenEventStream(
      VM.kIsolateStream,
      (ServiceEvent event) {
        if (event.kind == ServiceEvent.kIsolateSpawn) {
          expect(event.spawnToken, equals('someSpawnToken'));
          expect(event.spawnError, startsWith(
              'IsolateSpawnException: Unable to spawn isolate: '));
          expect(event.isolate, isNull);
          completer.complete();
          sub.cancel();
        }
      });

    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
        'token': 'someSpawnToken',
        'uri': '${fsUri}doesnotexist.dart',
    });
    expect(result['type'], equals('Success'));
    await completer.future;

    // Delete the fs.
    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
        'fsName': fsName,
    });
    expect(result['type'], equals('Success'));
  },

  (VM vm) async {
    // Create a new fs.
    var fsName = 'scratch';
    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
        'fsName': fsName,
      });
    expect(result['type'], equals('FileSystem'));
    expect(result['name'], equals('scratch'));
    expect(result['uri'], new isInstanceOf<String>());
    var fsUri = result['uri'];

    var filePaths = [
        'devfs_file0.dart',
        'devfs_file1.dart',
        'devfs_file2.dart'
    ];
    var scripts = [
'''
import 'dart:developer';
proofOfLife() => 'I live!';
main() {
  print('HELLO WORLD 1');
  debugger();
}
''',
'''
import 'dart:developer';
var globalArgs;
proofOfLife() => 'I live, \${globalArgs}!';
main(args) {
  globalArgs = args;
  print('HELLO WORLD 2');
  debugger();
}
''',
'''
import 'dart:developer';
var globalArgs;
var globalMsg;
proofOfLife() => 'I live, \${globalArgs}, \${globalMsg}!';
main(args, msg) {
  globalArgs = args;
  globalMsg = msg;
  print('HELLO WORLD 3');
  debugger();
}
''',
    ];

    // Write three scripts to the fs.
    for (int i = 0; i < 3; i++) {
      var fileContents = BASE64.encode(UTF8.encode(scripts[i]));
      result = await vm.invokeRpcNoUpgrade('_writeDevFSFile', {
        'fsName': fsName,
        'path': filePaths[i],
        'fileContents': fileContents
      });
      expect(result['type'], equals('Success'));
    }

    // Spawn the script with no arguments or message and make sure
    // that we are notified.
    Completer completer = new Completer();
    var sub;
    sub = await vm.listenEventStream(
      VM.kIsolateStream,
      (ServiceEvent event) {
        if (event.kind == ServiceEvent.kIsolateSpawn) {
          expect(event.spawnToken, equals('mySpawnToken0'));
          expect(event.isolate, isNotNull);
          expect(event.isolate.name, equals('devfs_file0.dart\$main'));
          completer.complete(event.isolate);
          sub.cancel();
        }
      });
    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
        'token': 'mySpawnToken0',
        'uri': '${fsUri}${filePaths[0]}',
    });
    expect(result['type'], equals('Success'));
    var spawnedIsolate = await completer.future;

    // Wait for the spawned isolate to hit a breakpoint.
    await spawnedIsolate.load();
    await hasStoppedAtBreakpoint(spawnedIsolate);

    // Make sure that we are running code from the spawned isolate.
    result = await spawnedIsolate.rootLibrary.evaluate('proofOfLife()');
    expect(result.type, equals('Instance'));
    expect(result.kind, equals('String'));
    expect(result.valueAsString, equals('I live!'));

    // Spawn the script with arguments.
    completer = new Completer();
    sub = await vm.listenEventStream(
      VM.kIsolateStream,
      (ServiceEvent event) {
        if (event.kind == ServiceEvent.kIsolateSpawn) {
          expect(event.spawnToken, equals('mySpawnToken1'));
          expect(event.isolate, isNotNull);
          expect(event.isolate.name, equals('devfs_file1.dart\$main'));
          completer.complete(event.isolate);
          sub.cancel();
        }
      });
    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
        'token': 'mySpawnToken1',
        'uri': '${fsUri}${filePaths[1]}',
        'args': ['one', 'two', 'three']
    });
    expect(result['type'], equals('Success'));
    spawnedIsolate = await completer.future;

    // Wait for the spawned isolate to hit a breakpoint.
    await spawnedIsolate.load();
    await hasStoppedAtBreakpoint(spawnedIsolate);

    // Make sure that we are running code from the spawned isolate.
    result = await spawnedIsolate.rootLibrary.evaluate('proofOfLife()');
    expect(result.type, equals('Instance'));
    expect(result.kind, equals('String'));
    expect(result.valueAsString, equals('I live, [one, two, three]!'));

    // Spawn the script with arguments and message
    completer = new Completer();
    sub = await vm.listenEventStream(
      VM.kIsolateStream,
      (ServiceEvent event) {
        if (event.kind == ServiceEvent.kIsolateSpawn) {
          expect(event.spawnToken, equals('mySpawnToken2'));
          expect(event.isolate, isNotNull);
          expect(event.isolate.name, equals('devfs_file2.dart\$main'));
          completer.complete(event.isolate);
          sub.cancel();
        }
      });
    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
        'token': 'mySpawnToken2',
        'uri': '${fsUri}${filePaths[2]}',
        'args': ['A', 'B', 'C'],
        'message': 'test'
    });
    expect(result['type'], equals('Success'));
    spawnedIsolate = await completer.future;

    // Wait for the spawned isolate to hit a breakpoint.
    await spawnedIsolate.load();
    await hasStoppedAtBreakpoint(spawnedIsolate);

    // Make sure that we are running code from the spawned isolate.
    result = await spawnedIsolate.rootLibrary.evaluate('proofOfLife()');
    expect(result.type, equals('Instance'));
    expect(result.kind, equals('String'));
    expect(result.valueAsString, equals('I live, [A, B, C], test!'));

    // Delete the fs.
    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
        'fsName': fsName,
    });
    expect(result['type'], equals('Success'));
  },
];

main(args) async => runVMTests(args, tests);
