// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This is a minimal dependency heart beat test for Observatory.

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'launcher.dart';
import 'service_client.dart';

class Expect {
  static void equals(dynamic actual, dynamic expected) {
    if (actual != expected) {
      throw 'Expected $actual == $expected';
    }
  }

  static void contains(String needle, String haystack) {
    if (!haystack.contains(needle)) {
      throw 'Expected $haystack to contain $needle';
    }
  }

  static void isTrue(bool tf) {
    if (tf != true) {
      throw 'Expected $tf to be true';
    }
  }

  static void isFalse(bool tf) {
    if (tf != false) {
      throw 'Expected $tf to be false';
    }
  }

  static void notExecuted() {
    throw 'Should not have hit';
  }

  static void isNotNull(dynamic a) {
    if (a == null) {
      throw 'Expected $a to not be null';
    }
  }
}

Future<String> readResponse(HttpClientResponse response) {
  final Completer<String> completer = Completer<String>();
  final StringBuffer contents = StringBuffer();
  response.transform(utf8.decoder).listen((String data) {
    contents.write(data);
  }, onDone: () => completer.complete(contents.toString()));
  return completer.future;
}

// Test accessing the service protocol over http.
Future<Null> testHttpProtocolRequest(Uri uri) async {
  uri = uri.replace(path: 'getVM');
  final HttpClient client = HttpClient();
  final HttpClientRequest request = await client.getUrl(uri);
  final HttpClientResponse response = await request.close();
  Expect.equals(response.statusCode, 200);
  final Map<String, dynamic> responseAsMap =
      json.decode(await readResponse(response)) as Map<String, dynamic>;
  Expect.equals(responseAsMap['jsonrpc'], '2.0');
  client.close();
}

// Test accessing the service protocol over ws.
Future<Null> testWebSocketProtocolRequest(Uri uri) async {
  uri = uri.replace(scheme: 'ws', path: 'ws');
  final WebSocket webSocketClient = await WebSocket.connect(uri.toString());
  final ServiceClient serviceClient = ServiceClient(webSocketClient);
  final Map<String, dynamic> response = await serviceClient.invokeRPC('getVM');
  Expect.equals(response['type'], 'VM');
  try {
    await serviceClient.invokeRPC('BART_SIMPSON');
    Expect.notExecuted();
  } catch (e) {
    // Method not found.
    Expect.equals((e as Map<String, dynamic>)['code'], -32601);
  }
}

// Test accessing an Observatory UI asset.
Future<Null> testHttpAssetRequest(Uri uri) async {
  uri = uri.replace(path: 'third_party/trace_viewer_full.html');
  final HttpClient client = HttpClient();
  final HttpClientRequest request = await client.getUrl(uri);
  final HttpClientResponse response = await request.close();
  Expect.equals(response.statusCode, 200);
  await response.drain();
  client.close();
}

Future<Null> testStartPaused(Uri uri) async {
  uri = uri.replace(scheme: 'ws', path: 'ws');
  final WebSocket webSocketClient = await WebSocket.connect(uri.toString());
  final Completer<dynamic> isolateStartedId = Completer<dynamic>();
  final Completer<dynamic> isolatePausedId = Completer<dynamic>();
  final Completer<dynamic> isolateResumeId = Completer<dynamic>();
  final ServiceClient serviceClient = ServiceClient(webSocketClient,
      isolateStartedId: isolateStartedId,
      isolatePausedId: isolatePausedId,
      isolateResumeId: isolateResumeId);
  await serviceClient
      .invokeRPC('streamListen', <String, String>{'streamId': 'Isolate'});
  await serviceClient
      .invokeRPC('streamListen', <String, String>{'streamId': 'Debug'});

  final Map<String, dynamic> response = await serviceClient.invokeRPC('getVM');
  Expect.equals(response['type'], 'VM');
  String isolateId;
  final List<dynamic> isolates = response['isolates'] as List<dynamic>;
  if (isolates.isNotEmpty) {
    isolateId = (isolates[0] as Map<String, String>)['id']!;
  } else {
    // Wait until isolate starts.
    isolateId = await isolateStartedId.future as String;
  }

  // Grab the isolate.
  Map<String, dynamic> isolate =
      await serviceClient.invokeRPC('getIsolate', <String, String>{
    'isolateId': isolateId,
  });
  Expect.equals(isolate['type'], 'Isolate');
  Expect.isNotNull(isolate['pauseEvent']);
  // If it is not runnable, wait until it becomes runnable.
  if (isolate['pauseEvent']['kind'] == 'None') {
    await isolatePausedId.future;
    isolate = await serviceClient.invokeRPC('getIsolate', <String, String>{
      'isolateId': isolateId,
    });
  }
  // Verify that it is paused at start.
  Expect.equals(isolate['pauseEvent']['kind'], 'PauseStart');

  // Resume the isolate.
  await serviceClient.invokeRPC('resume', <String, String>{
    'isolateId': isolateId,
  });
  // Wait until the isolate has resumed.
  await isolateResumeId.future;
  final Map<String, dynamic> resumedResponse = await serviceClient
      .invokeRPC('getIsolate', <String, String>{'isolateId': isolateId});
  Expect.equals(resumedResponse['type'], 'Isolate');
  Expect.isNotNull(resumedResponse['pauseEvent']);
  Expect.equals(resumedResponse['pauseEvent']['kind'], 'Resume');
}

typedef TestFunction = Future<Null> Function(Uri uri);

final List<TestFunction> basicTests = <TestFunction>[
  testHttpProtocolRequest,
  testWebSocketProtocolRequest,
  testHttpAssetRequest
];

final List<TestFunction> startPausedTests = <TestFunction>[
  // TODO(engine): Investigate difference in lifecycle events.
  // testStartPaused,
];

Future<bool> runTests(ShellLauncher launcher, List<TestFunction> tests) async {
  final ShellProcess? process = await launcher.launch();
  if (process == null) {
    return false;
  }
  final Uri uri = await process.waitForObservatory();
  try {
    for (int i = 0; i < tests.length; i++) {
      print('Executing test ${i + 1}/${tests.length}');
      await tests[i](uri);
    }
  } catch (e, st) {
    print('Observatory test failure: $e\n$st');
    exitCode = -1;
  }
  await process.kill();
  return exitCode == 0;
}

Future<Null> main(List<String> args) async {
  if (args.length < 2) {
    print('Usage: dart ${Platform.script} '
        '<sky_shell_executable> <main_dart> ...');
    return;
  }
  final String shellExecutablePath = args[0];
  final String mainDartPath = args[1];
  final List<String> extraArgs =
      args.length <= 2 ? <String>[] : args.sublist(2);

  final ShellLauncher launcher =
      ShellLauncher(shellExecutablePath, mainDartPath, false, extraArgs);

  final ShellLauncher startPausedlauncher =
      ShellLauncher(shellExecutablePath, mainDartPath, true, extraArgs);

  await runTests(launcher, basicTests);
  await runTests(startPausedlauncher, startPausedTests);
}
