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

/// This Element is part of MemoryDashboardElement.
///
/// The Element is stripped down version of AllocationProfileElement where
/// concepts like old and new space has been hidden away.
///
/// For each class in the system it is shown the Total number of instances
/// alive, the Total memory used by these instances, the number of instances
/// created since the last reset, the memory used by these instances.

import 'dart:async';
import 'dart:html';
import 'package:observatory/models.dart' as M;
import 'package:observatory/src/elements/class_ref.dart';
import 'package:observatory/src/elements/containers/virtual_collection.dart';
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/helpers/tag.dart';
import 'package:observatory/utils.dart';

enum _SortingField {
  accumulatedSize,
  accumulatedInstances,
  currentSize,
  currentInstances,
  className,
}

enum _SortingDirection { ascending, descending }

class MemoryAllocationsElement extends CustomElement implements Renderable {
  static const tag = const Tag<MemoryAllocationsElement>('memory-allocations',
      dependencies: const [ClassRefElement.tag, VirtualCollectionElement.tag]);

  RenderingScheduler<MemoryAllocationsElement> _r;

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

  M.IsolateRef _isolate;
  M.AllocationProfileRepository _repository;
  M.AllocationProfile _profile;
  M.EditorRepository _editor;
  _SortingField _sortingField = _SortingField.accumulatedInstances;
  _SortingDirection _sortingDirection = _SortingDirection.descending;

  M.IsolateRef get isolate => _isolate;

  factory MemoryAllocationsElement(M.IsolateRef isolate,
      M.EditorRepository editor, M.AllocationProfileRepository repository,
      {RenderingQueue queue}) {
    assert(isolate != null);
    assert(editor != null);
    assert(repository != null);
    MemoryAllocationsElement e = new MemoryAllocationsElement.created();
    e._r = new RenderingScheduler<MemoryAllocationsElement>(e, queue: queue);
    e._isolate = isolate;
    e._editor = editor;
    e._repository = repository;
    return e;
  }

  MemoryAllocationsElement.created() : super.created(tag);

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

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

  Future reload({bool gc = false, bool reset = false}) async {
    return _refresh(gc: gc, reset: reset);
  }

  void render() {
    if (_profile == null) {
      children = <Element>[
        new DivElement()
          ..classes = ['content-centered-big']
          ..children = <Element>[new HeadingElement.h2()..text = 'Loading...']
      ];
    } else {
      children = <Element>[
        new VirtualCollectionElement(
                _createCollectionLine, _updateCollectionLine,
                createHeader: _createCollectionHeader,
                search: _search,
                items: _profile.members
                    .where((member) =>
                        member.newSpace.accumulated.instances != 0 ||
                        member.newSpace.current.instances != 0 ||
                        member.oldSpace.accumulated.instances != 0 ||
                        member.oldSpace.current.instances != 0)
                    .toList()
                      ..sort(_createSorter()),
                queue: _r.queue)
            .element
      ];
    }
  }

  _createSorter() {
    var getter;
    switch (_sortingField) {
      case _SortingField.accumulatedSize:
        getter = _getAccumulatedSize;
        break;
      case _SortingField.accumulatedInstances:
        getter = _getAccumulatedInstances;
        break;
      case _SortingField.currentSize:
        getter = _getCurrentSize;
        break;
      case _SortingField.currentInstances:
        getter = _getCurrentInstances;
        break;
      case _SortingField.className:
        getter = (M.ClassHeapStats s) => s.clazz.name;
        break;
    }
    switch (_sortingDirection) {
      case _SortingDirection.ascending:
        int sort(M.ClassHeapStats a, M.ClassHeapStats b) {
          return getter(a).compareTo(getter(b));
        }
        return sort;
      case _SortingDirection.descending:
        int sort(M.ClassHeapStats a, M.ClassHeapStats b) {
          return getter(b).compareTo(getter(a));
        }
        return sort;
    }
  }

  static HtmlElement _createCollectionLine() => new DivElement()
    ..classes = ['collection-item']
    ..children = <Element>[
      new SpanElement()
        ..classes = ['bytes']
        ..text = '0B',
      new SpanElement()
        ..classes = ['instances']
        ..text = '0',
      new SpanElement()
        ..classes = ['bytes']
        ..text = '0B',
      new SpanElement()
        ..classes = ['instances']
        ..text = '0',
      new SpanElement()..classes = ['name']
    ];

  List<HtmlElement> _createCollectionHeader() {
    final resetAccumulators = new ButtonElement();
    return [
      new DivElement()
        ..classes = ['collection-item']
        ..children = <Element>[
          new SpanElement()
            ..classes = ['group']
            ..nodes = [
              new Text('Since Last '),
              resetAccumulators
                ..text = 'Reset'
                ..title = 'Reset'
                ..onClick.listen((_) async {
                  resetAccumulators.disabled = true;
                  await _refresh(reset: true);
                  resetAccumulators.disabled = false;
                })
            ],
          new SpanElement()
            ..classes = ['group']
            ..text = 'Current'
        ],
      new DivElement()
        ..classes = ['collection-item']
        ..children = <Element>[
          _createHeaderButton(const ['bytes'], 'Size',
              _SortingField.accumulatedSize, _SortingDirection.descending),
          _createHeaderButton(const ['instances'], 'Instances',
              _SortingField.accumulatedInstances, _SortingDirection.descending),
          _createHeaderButton(const ['bytes'], 'Size',
              _SortingField.currentSize, _SortingDirection.descending),
          _createHeaderButton(const ['instances'], 'Instances',
              _SortingField.currentInstances, _SortingDirection.descending),
          _createHeaderButton(const ['name'], 'Class', _SortingField.className,
              _SortingDirection.ascending)
        ],
    ];
  }

  ButtonElement _createHeaderButton(List<String> classes, String text,
          _SortingField field, _SortingDirection direction) =>
      new ButtonElement()
        ..classes = classes
        ..text = _sortingField != field
            ? text
            : _sortingDirection == _SortingDirection.ascending
                ? '$text▼'
                : '$text▲'
        ..onClick.listen((_) => _setSorting(field, direction));

  void _setSorting(_SortingField field, _SortingDirection defaultDirection) {
    if (_sortingField == field) {
      switch (_sortingDirection) {
        case _SortingDirection.descending:
          _sortingDirection = _SortingDirection.ascending;
          break;
        case _SortingDirection.ascending:
          _sortingDirection = _SortingDirection.descending;
          break;
      }
    } else {
      _sortingDirection = defaultDirection;
      _sortingField = field;
    }
    _r.dirty();
  }

  void _updateCollectionLine(Element e, itemDynamic, index) {
    M.ClassHeapStats item = itemDynamic;
    e.children[0].text = Utils.formatSize(_getAccumulatedSize(item));
    e.children[1].text = '${_getAccumulatedInstances(item)}';
    e.children[2].text = Utils.formatSize(_getCurrentSize(item));
    e.children[3].text = '${_getCurrentInstances(item)}';
    if (item.clazz == null) {
      e.children[4] = new SpanElement()
        ..text = item.displayName
        ..classes = ['name'];
      return;
    }
    e.children[4] = (new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
          ..classes = ['name'])
        .element;
    Element.clickEvent.forTarget(e.children[4], useCapture: true).listen((e) {
      if (_editor.isAvailable) {
        e.preventDefault();
        _editor.openClass(isolate, item.clazz);
      }
    });
  }

  bool _search(Pattern pattern, itemDynamic) {
    M.ClassHeapStats item = itemDynamic;
    final String value = item.clazz?.name ?? item.displayName;
    return value.contains(pattern);
  }

  Future _refresh({bool gc: false, bool reset: false}) async {
    _profile = null;
    _r.dirty();
    _profile =
        await _repository.get(_isolate, gc: gc, reset: reset, combine: true);
    _r.dirty();
  }

  static int _getAccumulatedSize(M.ClassHeapStats s) =>
      s.newSpace.accumulated.bytes + s.oldSpace.accumulated.bytes;
  static int _getAccumulatedInstances(M.ClassHeapStats s) =>
      s.newSpace.accumulated.instances + s.oldSpace.accumulated.instances;
  static int _getCurrentSize(M.ClassHeapStats s) =>
      s.newSpace.current.bytes + s.oldSpace.current.bytes;
  static int _getCurrentInstances(M.ClassHeapStats s) =>
      s.newSpace.current.instances + s.oldSpace.current.instances;
}
