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

// ignore_for_file: avoid_dynamic_calls

/// A script to track the high water-mark of memory usage of an application.
/// To monitor how much memory dart2js is using, run dart2js as follows:
///
///     DART_VM_OPTIONS=--observe dart2js ...
///
/// and run this script immediately after.
library compiler.tool.track_memory;

import 'dart:math' show max;
import 'dart:io';
import 'dart:async';

import 'dart:convert';

/// Socket to connect to the vm observatory service.
late WebSocket socket;

main(args) async {
  _printHeader();
  _showProgress(0, 0, 0, 0);
  try {
    var port = args.length > 0 ? int.parse(args[0]) : 8181;
    socket = await WebSocket.connect('ws://localhost:$port/ws');
    socket.listen(_handleResponse);
    await _resumeMainIsolateIfPaused();
    _streamListen('GC');
    _streamListen('Isolate');
    _streamListen('Debug');
  } catch (e) {
    // TODO(sigmund): add better error messages, maybe option to retry.
    print('\n${_RED}error${_NONE}: $e');
    print('usage:\n'
        '  Start a Dart process with the --observe flag (and optionally '
        'the --pause_isolates_on_start flag), then invoke:\n'
        '      dart tool/track_memory.dart [<port>]\n'
        '  by default port is 8181');
  }
}

/// Internal counter for request ids.
int _requestId = 0;
Map _pendingResponses = {};

/// Subscribe to listen to a vm service data stream.
_streamListen(String streamId) =>
    _sendMessage('streamListen', {'streamId': '$streamId'});

/// Tell the vm service to resume a specific isolate.
_resumeIsolate(String isolateId) =>
    _sendMessage('resume', {'isolateId': '$isolateId'});

/// Resumes the main isolate if it was paused on start.
_resumeMainIsolateIfPaused() async {
  var vm = await _sendMessage('getVM');
  var isolateId = vm['isolates'][0]['id'];
  var isolate = await _sendMessage('getIsolate', {'isolateId': isolateId});
  bool isPaused = isolate['pauseEvent']['kind'] == 'PauseStart';
  if (isPaused) _resumeIsolate(isolateId);
}

/// Send a message to the vm service.
Future _sendMessage(String method, [Map args = const {}]) {
  var id = _requestId++;
  _pendingResponses[id] = new Completer();
  socket.add(jsonEncode({
    'jsonrpc': '2.0',
    'id': '$id',
    'method': '$method',
    'params': args,
  }));
  return _pendingResponses[id].future;
}

/// Handle all responses
void _handleResponse(Object? s) {
  var json = jsonDecode(s as String);
  if (json['method'] != 'streamNotify') {
    var id = json['id'];
    if (id is String) id = int.parse(id);
    if (id == null || !_pendingResponses.containsKey(id)) return;
    _pendingResponses.remove(id).complete(json['result']);
    return;
  }

  // isolate pauses on exit automatically. We detect this to stop and exit.
  if (json['params']['streamId'] == 'Debug') {
    _handleDebug(json);
  } else if (json['params']['streamId'] == 'Isolate') {
    _handleIsolate(json);
  } else if (json['params']['streamId'] == 'GC') {
    _handleGC(json);
  }
}

/// Handle a `Debug` notification.
_handleDebug(Map json) {
  var isolateId = json['params']['event']['isolate']['id'];
  if (json['params']['event']['kind'] == 'PauseStart') {
    _resumeIsolate(isolateId);
  }
  if (json['params']['event']['kind'] == 'PauseExit') {
    _resumeIsolate(isolateId);
  }
}

/// Handle a `Isolate` notification.
_handleIsolate(Map json) {
  if (json['params']['event']['kind'] == 'IsolateExit') {
    print('');
    socket.close();
  }
}

/// Handle a `GC` notification.
_handleGC(Map json) {
  // print(new JsonEncoder.withIndent(' ').convert(json));
  var event = json['params']['event'];
  var newUsed = event['new']['used'];
  var newCapacity = event['new']['capacity'];
  var oldUsed = event['old']['used'];
  var oldCapacity = event['old']['capacity'];
  _showProgress(newUsed, newCapacity, oldUsed, oldCapacity);
}

int lastNewUsed = 0;
int lastOldUsed = 0;
int lastMaxUsed = 0;
int lastNewCapacity = 0;
int lastOldCapacity = 0;
int lastMaxCapacity = 0;

/// Shows a status line with use/capacity numbers for new/old/total/max,
/// highlighting in red when capacity increases, and in green when it decreases.
_showProgress(newUsed, newCapacity, oldUsed, oldCapacity) {
  var sb = new StringBuffer();
  sb.write('\r '); // replace the status-line in place
  _writeNumber(sb, lastNewUsed, newUsed);
  _writeNumber(sb, lastNewCapacity, newCapacity, color: true);

  sb.write(' | ');
  _writeNumber(sb, lastOldUsed, oldUsed);
  _writeNumber(sb, lastOldCapacity, oldCapacity, color: true);

  sb.write(' | ');
  _writeNumber(sb, lastNewUsed + lastOldUsed, newUsed + oldUsed);
  _writeNumber(sb, lastNewCapacity + lastOldCapacity, newCapacity + oldCapacity,
      color: true);

  sb.write(' | ');
  int maxUsed = max(lastMaxUsed, newUsed + oldUsed);
  int maxCapacity = max(lastMaxCapacity, newCapacity + oldCapacity);
  _writeNumber(sb, lastMaxUsed, maxUsed);
  _writeNumber(sb, lastMaxCapacity, maxCapacity, color: true);
  stdout.write('$sb');

  lastNewUsed = newUsed;
  lastOldUsed = oldUsed;
  lastMaxUsed = maxUsed;
  lastNewCapacity = newCapacity;
  lastOldCapacity = oldCapacity;
  lastMaxCapacity = maxCapacity;
}

const mega = 1024 * 1024;
_writeNumber(sb, before, now, {color = false}) {
  if (color)
    sb.write(before < now
        ? _RED
        : before > now
            ? _GREEN
            : '');
  String string;
  if (now < 1024) {
    string = ' ${now}b';
  } else if (now < mega) {
    string = ' ${(now / 1024).toStringAsFixed(0)}K';
  } else {
    string = ' ${(now / mega).toStringAsFixed(1)}M';
  }
  if (string.length < 10) string = '${' ' * (8 - string.length)}$string';
  sb.write(string);
  if (color) sb.write(before != now ? _NONE : '');
  return before > now;
}

_printHeader() {
  print('''
Memory usage:
 new generation   | old generation   | total            | max
  in-use/capacity |  in-use/capacity |  in-use/capacity |  in-use/capacity ''');
}

const _RED = '\x1b[31m';
const _GREEN = '\x1b[32m';
const _NONE = '\x1b[0m';
