// 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/models.dart' as M;
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(M.InstanceKind.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(M.InstanceKind.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(M.InstanceKind.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);
