// 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.

import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'dart:isolate';

import 'package:compiler/src/dart2js.dart' as dart2js_main;
import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:vm_service/vm_service_io.dart' as vm_service_io;

class Result {
  const Result(
      this.rssOnStart, this.rssOnEnd, this.heapOnStart, this.heapOnEnd);

  final int rssOnStart;
  final int rssOnEnd;
  final int heapOnStart;
  final int heapOnEnd;
}

class StartMessage {
  const StartMessage(this.wsUri, this.groupRefId, this.sendPort);

  final String wsUri;
  final String groupRefId;
  final SendPort sendPort;
}

class SpawnMemory {
  SpawnMemory(this.name, this.wsUri, this.groupRefId);

  Future<void> report() async {
    const numberOfRuns = 5;

    int sumDeltaRssOnStart = 0;
    int sumDeltaRssOnEnd = 0;
    int sumDeltaHeapOnStart = 0;
    int sumDeltaHeapOnEnd = 0;
    for (int i = 0; i < numberOfRuns; i++) {
      final receivePort = ReceivePort();
      final beforeRss = ProcessInfo.currentRss;
      final beforeHeap = await currentHeapUsage(wsUri, groupRefId);

      final startMessage =
          StartMessage(wsUri, groupRefId, receivePort.sendPort);
      await Isolate.spawn(isolateCompiler, startMessage);

      final Result result = await receivePort.first;
      sumDeltaRssOnStart += result.rssOnStart - beforeRss;
      sumDeltaRssOnEnd += result.rssOnEnd - beforeRss;
      sumDeltaHeapOnStart += result.heapOnStart - beforeHeap;
      sumDeltaHeapOnEnd += result.heapOnEnd - beforeHeap;
    }
    print(
        "${name}RssOnStart(MemoryUse): ${sumDeltaRssOnStart ~/ numberOfRuns}");
    print("${name}RssOnEnd(MemoryUse): ${sumDeltaRssOnEnd ~/ numberOfRuns}");
    print(
        "${name}HeapOnStart(MemoryUse): ${sumDeltaHeapOnStart ~/ numberOfRuns}");
    print("${name}HeapOnEnd(MemoryUse): ${sumDeltaHeapOnEnd ~/ numberOfRuns}");
  }

  final String name;
  final String wsUri;
  final String groupRefId;
  RawReceivePort receivePort;
}

Future<void> isolateCompiler(StartMessage startMessage) async {
  final rssOnStart = ProcessInfo.currentRss;
  final heapOnStart =
      await currentHeapUsage(startMessage.wsUri, startMessage.groupRefId);
  await runZoned(
      () => dart2js_main.internalMain(<String>[
            "benchmarks/IsolateSpawnMemory/dart/helloworld.dart",
            '--libraries-spec=sdk/lib/libraries.json'
          ]),
      zoneSpecification: ZoneSpecification(
          print: (Zone self, ZoneDelegate parent, Zone zone, String line) {}));
  startMessage.sendPort.send(Result(
      rssOnStart,
      ProcessInfo.currentRss,
      heapOnStart,
      await currentHeapUsage(startMessage.wsUri, startMessage.groupRefId)));
  ReceivePort(); // prevent isolate from exiting to ensure Rss monotonically grows
}

Future<int> currentHeapUsage(String wsUri, String groupRefId) async {
  final vm_service.VmService vmService =
      await vm_service_io.vmServiceConnectUri(wsUri);
  final vm_service.MemoryUsage usage =
      await vmService.getIsolateGroupMemoryUsage(groupRefId);
  vmService.dispose();
  return usage.heapUsage + usage.externalUsage;
}

Future<void> main() async {
  final ServiceProtocolInfo info = await Service.controlWebServer(enable: true);
  final Uri observatoryUri = info.serverUri;
  final String wsUri =
      'ws://${observatoryUri.authority}${observatoryUri.path}ws';
  final vm_service.VmService vmService =
      await vm_service_io.vmServiceConnectUri(wsUri);
  final String mainGroupRefId = await getMainGroupRefId(vmService);
  vmService.dispose();

  await SpawnMemory("IsolateSpawnMemory.Dart2JSDelta", wsUri, mainGroupRefId)
      .report();
}

Future<String> getMainGroupRefId(vm_service.VmService vmService) async {
  final vm = await vmService.getVM();
  for (vm_service.IsolateGroupRef groupRef in vm.isolateGroups) {
    final vm_service.IsolateGroup group =
        await vmService.getIsolateGroup(groupRef.id);
    for (vm_service.IsolateRef isolateRef in group.isolates) {
      final isolateOrSentinel = await vmService.getIsolate(isolateRef.id);
      if (isolateOrSentinel is vm_service.Isolate) {
        final vm_service.Isolate isolate = isolateOrSentinel;
        if (isolate.name == 'main') {
          return groupRef.id;
        }
      }
    }
  }
  throw "Could not find main isolate";
}
