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

library heap_map_element;

import 'dart:async';
import 'dart:html';
import 'dart:math';
import 'package:observatory/models.dart' as M;
import 'package:observatory/service.dart' as S;
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/helpers/nav_bar.dart';
import 'package:observatory/src/elements/helpers/nav_menu.dart';
import 'package:observatory/src/elements/helpers/custom_element.dart';
import 'package:observatory/src/elements/helpers/uris.dart';
import 'package:observatory/src/elements/nav/isolate_menu.dart';
import 'package:observatory/src/elements/nav/notify.dart';
import 'package:observatory/src/elements/nav/refresh.dart';
import 'package:observatory/src/elements/nav/top_menu.dart';
import 'package:observatory/src/elements/nav/vm_menu.dart';

class HeapMapElement extends CustomElement implements Renderable {
  late RenderingScheduler<HeapMapElement> _r;

  Stream<RenderedEvent<HeapMapElement>> get onRendered => _r.onRendered;

  late M.VM _vm;
  late M.IsolateRef _isolate;
  late M.EventRepository _events;
  late M.NotificationRepository _notifications;
  M.VMRef get vm => _vm;
  M.IsolateRef get isolate => _isolate;
  M.NotificationRepository get notifications => _notifications;

  factory HeapMapElement(M.VM vm, M.IsolateRef isolate,
      M.EventRepository events, M.NotificationRepository notifications,
      {RenderingQueue? queue}) {
    assert(vm != null);
    assert(isolate != null);
    assert(events != null);
    assert(notifications != null);
    HeapMapElement e = new HeapMapElement.created();
    e._r = new RenderingScheduler<HeapMapElement>(e, queue: queue);
    e._vm = vm;
    e._isolate = isolate;
    e._events = events;
    e._notifications = notifications;
    return e;
  }

  HeapMapElement.created() : super.created('heap-map');

  @override
  attached() {
    super.attached();
    _r.enable();
    _refresh();
  }

  @override
  detached() {
    super.detached();
    _r.disable(notify: true);
    children = <Element>[];
  }

  CanvasElement? _canvas;
  dynamic _fragmentationData;
  int? _pageHeight;
  final _classIdToColor = {};
  final _colorToClassId = {};
  final _classIdToName = {};

  static final _freeColor = [255, 255, 255, 255];
  static final _pageSeparationColor = [0, 0, 0, 255];
  static const _PAGE_SEPARATION_HEIGHT = 4;
  // Many browsers will not display a very tall canvas.
  // TODO(koda): Improve interface for huge heaps.
  static const _MAX_CANVAS_HEIGHT = 6000;

  String _status = 'Loading';
  S.ServiceMap? _fragmentation;

  void render() {
    if (_canvas == null) {
      _canvas = new CanvasElement()
        ..width = 1
        ..height = 1
        ..onMouseMove.listen(_handleMouseMove);
    }

    // Set hover text to describe the object under the cursor.
    _canvas!.title = _status;

    children = <Element>[
      navBar(<Element>[
        new NavTopMenuElement(queue: _r.queue).element,
        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
        navMenu('heap map'),
        (new NavRefreshElement(label: 'Mark-Compact', queue: _r.queue)
              ..onRefresh.listen((_) => _refresh(gc: "mark-compact")))
            .element,
        (new NavRefreshElement(label: 'Mark-Sweep', queue: _r.queue)
              ..onRefresh.listen((_) => _refresh(gc: "mark-sweep")))
            .element,
        (new NavRefreshElement(label: 'Scavenge', queue: _r.queue)
              ..onRefresh.listen((_) => _refresh(gc: "scavenge")))
            .element,
        (new NavRefreshElement(queue: _r.queue)
              ..onRefresh.listen((_) => _refresh()))
            .element,
        (new NavNotifyElement(_notifications, queue: _r.queue)).element
      ]),
      new DivElement()
        ..classes = ['content-centered-big']
        ..children = <Element>[
          new HeadingElement.h2()..text = _status,
          new HRElement(),
        ],
      new DivElement()
        ..classes = ['flex-row']
        ..children = <Element>[_canvas!]
    ];
  }

  // Encode color as single integer, to enable using it as a map key.
  int _packColor(Iterable<int> color) {
    int packed = 0;
    for (var component in color) {
      packed = packed * 256 + component;
    }
    return packed;
  }

  void _addClass(int classId, String name, Iterable<int> color) {
    _classIdToName[classId] = name.split('@')[0];
    _classIdToColor[classId] = color;
    _colorToClassId[_packColor(color)] = classId;
  }

  void _updateClassList(classList, int freeClassId) {
    for (var member in classList['classes']) {
      if (member is! S.Class) {
        // TODO(turnidge): The printing for some of these non-class
        // members is broken.  Fix this:
        //
        // Logger.root.info('$member');
        print('Ignoring non-class in class list');
        continue;
      }
      var classId = int.parse(member.id!.split('/').last);
      var color = _classIdToRGBA(classId);
      _addClass(classId, member.name!, color);
    }
    _addClass(freeClassId, 'Free', _freeColor);
    _addClass(0, '', _pageSeparationColor);
  }

  Iterable<int> _classIdToRGBA(int classId) {
    // TODO(koda): Pick random hue, but fixed saturation and value.
    var rng = new Random(classId);
    return [rng.nextInt(128), rng.nextInt(128), rng.nextInt(128), 255];
  }

  String _classNameAt(Point<num> point) {
    var color = new PixelReference(_fragmentationData, point).color;
    return _classIdToName[_colorToClassId[_packColor(color)]];
  }

  ObjectInfo? _objectAt(Point<num> point) {
    if (_fragmentation == null || _canvas == null) {
      return null;
    }
    var pagePixels = _pageHeight! * _fragmentationData.width;
    var index = new PixelReference(_fragmentationData, point).index;
    var pageIndex = index ~/ pagePixels;
    num pageOffset = index % pagePixels;
    var pages = _fragmentation!['pages'];
    if (pageIndex < 0 || pageIndex >= pages.length) {
      return null;
    }
    // Scan the page to find start and size.
    var page = pages[pageIndex];
    var objects = page['objects'];
    var offset = 0;
    var size = 0;
    for (var i = 0; i < objects.length; i += 2) {
      size = objects[i];
      offset += size;
      if (offset > pageOffset) {
        pageOffset = offset - size;
        break;
      }
    }
    return new ObjectInfo(
        int.parse(page['objectStart']) +
            pageOffset * _fragmentation!['unitSizeBytes'],
        size * _fragmentation!['unitSizeBytes']);
  }

  void _handleMouseMove(MouseEvent event) {
    var info = _objectAt(event.offset);
    if (info == null) {
      _status = '';
      _r.dirty();
      return;
    }
    var addressString = '${info.size}B @ 0x${info.address.toRadixString(16)}';
    var className = _classNameAt(event.offset);
    _status = (className == '') ? '-' : '$className $addressString';
    _r.dirty();
  }

  void _updateFragmentationData() {
    if (_fragmentation == null || _canvas == null) {
      return;
    }
    _updateClassList(
        _fragmentation!['classList'], _fragmentation!['freeClassId']);
    var pages = _fragmentation!['pages'];
    var width = max(_canvas!.parent!.client.width, 1) as int;
    _pageHeight = _PAGE_SEPARATION_HEIGHT +
        (_fragmentation!['pageSizeBytes'] as int) ~/
            (_fragmentation!['unitSizeBytes'] as int) ~/
            width;
    var height = min(_pageHeight! * pages.length, _MAX_CANVAS_HEIGHT) as int;
    _fragmentationData = _canvas!.context2D.createImageData(width, height);
    _canvas!.width = _fragmentationData.width;
    _canvas!.height = _fragmentationData.height;
    _renderPages(0);
  }

  // Renders and draws asynchronously, one page at a time to avoid
  // blocking the UI.
  void _renderPages(int startPage) {
    var pages = _fragmentation!['pages'];
    _status = 'Loaded $startPage of ${pages.length} pages';
    _r.dirty();
    var startY = (startPage * _pageHeight!).round();
    var endY = startY + _pageHeight!.round();
    if (startPage >= pages.length || endY > _fragmentationData.height) {
      return;
    }
    var pixel = new PixelReference(_fragmentationData, new Point(0, startY));
    var objects = pages[startPage]['objects'];
    for (var i = 0; i < objects.length; i += 2) {
      var count = objects[i];
      var classId = objects[i + 1];
      var color = _classIdToColor[classId];
      while (count-- > 0) {
        pixel.color = color;
        pixel = pixel.next();
      }
    }
    while (pixel.point.y < endY) {
      pixel.color = _pageSeparationColor;
      pixel = pixel.next();
    }
    _canvas!.context2D.putImageData(
        _fragmentationData, 0, 0, 0, startY, _fragmentationData.width, endY);
    // Continue with the next page, asynchronously.
    new Future(() {
      _renderPages(startPage + 1);
    });
  }

  Future _refresh({String? gc}) {
    final isolate = _isolate as S.Isolate;
    var params = {};
    if (gc != null) {
      params['gc'] = gc;
    }
    return isolate.invokeRpc('_getHeapMap', params).then((serviceObject) {
      S.ServiceMap response = serviceObject as S.ServiceMap;
      assert(response['type'] == 'HeapMap');
      _fragmentation = response;
      _updateFragmentationData();
    });
  }
}

// A reference to a particular pixel of ImageData.
class PixelReference {
  final _data;
  var _dataIndex;
  static const NUM_COLOR_COMPONENTS = 4;

  PixelReference(ImageData data, Point<num> point)
      : _data = data,
        _dataIndex = (point.y * data.width + point.x) * NUM_COLOR_COMPONENTS;

  PixelReference._fromDataIndex(this._data, this._dataIndex);

  Point<num> get point => new Point(index % _data.width, index ~/ _data.width);

  void set color(Iterable<int> color) {
    _data.data.setRange(_dataIndex, _dataIndex + NUM_COLOR_COMPONENTS, color);
  }

  Iterable<int> get color =>
      _data.data.getRange(_dataIndex, _dataIndex + NUM_COLOR_COMPONENTS);

  // Returns the next pixel in row-major order.
  PixelReference next() => new PixelReference._fromDataIndex(
      _data, _dataIndex + NUM_COLOR_COMPONENTS);

  // The row-major index of this pixel.
  int get index => _dataIndex ~/ NUM_COLOR_COMPONENTS;
}

class ObjectInfo {
  final address;
  final size;
  ObjectInfo(this.address, this.size);
}
