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

library heap_snapshot_element;

import 'dart:async';
import 'dart:html';
import 'observatory_element.dart';
import 'package:observatory/app.dart';
import 'package:observatory/service.dart';
import 'package:observatory/elements.dart';
import 'package:observatory/object_graph.dart';
import 'package:polymer/polymer.dart';
import 'package:logging/logging.dart';

class DominatorTreeRow extends TableTreeRow {
  final ObjectVertex vertex;
  final HeapSnapshot snapshot;

  var _domTreeChildren;
  get domTreeChildren {
    if (_domTreeChildren == null) {
      _domTreeChildren = vertex.dominatorTreeChildren();
    }
    return _domTreeChildren;
  }

  DominatorTreeRow(TableTree tree,
                   TableTreeRow parent,
                   this.vertex,
                   this.snapshot)
      : super(tree, parent) {
  }

  bool hasChildren() {
    return domTreeChildren.length > 0;
  }

  static const int kMaxChildren = 100;
  static const int kMinRetainedSize = 4096;

  void onShow() {
    super.onShow();
    if (children.length == 0) {
      domTreeChildren.sort((a, b) => b.retainedSize - a.retainedSize);
      int includedChildren = 0;
      for (var childVertex in domTreeChildren) {
        if (childVertex.retainedSize >= kMinRetainedSize) {
          if (++includedChildren <= kMaxChildren) {
            var row = new DominatorTreeRow(tree, this, childVertex, snapshot);
            children.add(row);
          }
        }
      }
    }

    var firstColumn = flexColumns[0];
    firstColumn.style.justifyContent = 'flex-start';
    firstColumn.style.position = 'relative';
    firstColumn.style.alignItems = 'center';
    firstColumn.style.setProperty('overflow-x', 'hidden');

    var percentRetained = vertex.retainedSize / snapshot.graph.size;
    var percentNode = new SpanElement();
    percentNode.text =  Utils.formatPercentNormalized(percentRetained);
    percentNode.style.minWidth = '5em';
    percentNode.style.textAlign = 'right';
    percentNode.title = "Percent of heap being retained";
    percentNode.style.display = 'inline-block';
    firstColumn.children.add(percentNode);

    var gap = new SpanElement();
    gap.style.minWidth = '1em';
    gap.style.display = 'inline-block';
    firstColumn.children.add(gap);

    AnyServiceRefElement objectRef = new Element.tag("any-service-ref");
    snapshot.isolate.getObjectByAddress(vertex.address).then((obj) {
      objectRef.ref = obj;
    });
    objectRef.style.alignSelf = 'center';
    firstColumn.children.add(objectRef);

    var secondColumn = flexColumns[1];
    secondColumn.style.justifyContent = 'flex-end';
    secondColumn.style.position = 'relative';
    secondColumn.style.alignItems = 'center';
    secondColumn.style.paddingRight = '0.5em';
    secondColumn.text = Utils.formatSize(vertex.retainedSize);
  }
}


class MergedVerticesRow extends TableTreeRow {
  final Isolate isolate;
  final List<MergedVertex> mergedVertices;

  MergedVerticesRow(TableTree tree,
                   TableTreeRow parent,
                   this.isolate,
                   this.mergedVertices)
      : super(tree, parent) {
  }

  bool hasChildren() {
    return mergedVertices.length > 0;
  }

  void onShow() {
    super.onShow();

    if (children.length == 0) {
      mergedVertices.sort((a, b) => b.shallowSize - a.shallowSize);
      for (var mergedVertex in mergedVertices) {
        if (mergedVertex.instances > 0) {
          var row = new MergedVertexRow(tree, this, isolate, mergedVertex);
          children.add(row);
        }
      }
    }
  }
}

class MergedVertexRow extends TableTreeRow {
  final Isolate isolate;
  final MergedVertex vertex;

  MergedVertexRow(TableTree tree,
                  TableTreeRow parent,
                  this.isolate,
                  this.vertex)
      : super(tree, parent) {
  }

  bool hasChildren() {
    return vertex.outgoingEdges.length > 0 ||
           vertex.incomingEdges.length > 0;
  }

  void onShow() {
    super.onShow();
    if (children.length == 0) {
      children.add(new MergedEdgesRow(tree, this, isolate, vertex, true));
      children.add(new MergedEdgesRow(tree, this, isolate, vertex, false));
    }


    var firstColumn = flexColumns[0];
    firstColumn.style.justifyContent = 'flex-start';
    firstColumn.style.position = 'relative';
    firstColumn.style.alignItems = 'center';

    var percentNode = new SpanElement();
    percentNode.text = "${vertex.instances} instances of";
    percentNode.style.minWidth = '5em';
    percentNode.style.textAlign = 'right';
    firstColumn.children.add(percentNode);

    var gap = new SpanElement();
    gap.style.minWidth = '1em';
    gap.style.display = 'inline-block';
    firstColumn.children.add(gap);

    ClassRefElement classRef = new Element.tag("class-ref");
    classRef.ref = isolate.getClassByCid(vertex.cid);
    classRef.style.alignSelf = 'center';
    firstColumn.children.add(classRef);

    var secondColumn = flexColumns[1];
    secondColumn.style.justifyContent = 'flex-end';
    secondColumn.style.position = 'relative';
    secondColumn.style.alignItems = 'center';
    secondColumn.style.paddingRight = '0.5em';
    secondColumn.text = Utils.formatSize(vertex.shallowSize);
  }
}

class MergedEdgesRow extends TableTreeRow {
  final Isolate isolate;
  final MergedVertex vertex;
  final bool outgoing;

  MergedEdgesRow(TableTree tree,
                 TableTreeRow parent,
                 this.isolate,
                 this.vertex,
                 this.outgoing)
      : super(tree, parent) {
  }

  bool hasChildren() {
    return outgoing
            ? vertex.outgoingEdges.length > 0
            : vertex.incomingEdges.length > 0;
  }

  void onShow() {
    super.onShow();
    if (children.length == 0) {
      if (outgoing) {
        var outgoingEdges = vertex.outgoingEdges.values.toList();
        outgoingEdges.sort((a, b) => b.shallowSize - a.shallowSize);
        for (var edge in outgoingEdges) {
          if (edge.count > 0) {
            var row = new MergedEdgeRow(tree, this, isolate, edge, true);
            children.add(row);
          }
        }
      } else {
        vertex.incomingEdges.sort((a, b) => b.shallowSize - a.shallowSize);
        for (var edge in vertex.incomingEdges) {
          if (edge.count > 0) {
            var row = new MergedEdgeRow(tree, this, isolate, edge, false);
            children.add(row);
          }
        }
      }
    }

    var count = 0;
    var shallowSize = 0;
    var edges = outgoing ? vertex.outgoingEdges.values : vertex.incomingEdges;
    for (var edge in edges) {
      count += edge.count;
      shallowSize += edge.shallowSize;
    }

    var firstColumn = flexColumns[0];
    firstColumn.style.justifyContent = 'flex-start';
    firstColumn.style.position = 'relative';
    firstColumn.style.alignItems = 'center';

    var countNode = new SpanElement();
    countNode.text = "$count";
    countNode.style.minWidth = '5em';
    countNode.style.textAlign = 'right';
    firstColumn.children.add(countNode);

    var gap = new SpanElement();
    gap.style.minWidth = '1em';
    gap.style.display = 'inline-block';
    firstColumn.children.add(gap);

    var labelNode = new SpanElement();
    labelNode.text = outgoing ? "Outgoing references" : "Incoming references";
    firstColumn.children.add(labelNode);

    var secondColumn = flexColumns[1];
    secondColumn.style.justifyContent = 'flex-end';
    secondColumn.style.position = 'relative';
    secondColumn.style.alignItems = 'center';
    secondColumn.style.paddingRight = '0.5em';
    secondColumn.text = Utils.formatSize(shallowSize);
  }
}

class MergedEdgeRow extends TableTreeRow {
  final Isolate isolate;
  final MergedEdge edge;
  final bool outgoing;

  MergedEdgeRow(TableTree tree,
                TableTreeRow parent,
                this.isolate,
                this.edge,
                this.outgoing)
      : super(tree, parent) {
  }

  bool hasChildren() => false;

  void onShow() {
    super.onShow();

    var firstColumn = flexColumns[0];
    firstColumn.style.justifyContent = 'flex-start';
    firstColumn.style.position = 'relative';
    firstColumn.style.alignItems = 'center';

    var percentNode = new SpanElement();
    var preposition = outgoing ? "to" : "from";
    percentNode.text = "${edge.count} references $preposition instances of";
    percentNode.style.minWidth = '5em';
    percentNode.style.textAlign = 'right';
    firstColumn.children.add(percentNode);

    var gap = new SpanElement();
    gap.style.minWidth = '1em';
    gap.style.display = 'inline-block';
    firstColumn.children.add(gap);

    MergedVertex v = outgoing ? edge.target : edge.source;
    if (v.cid == 0) {
      var rootName = new SpanElement();
      rootName.text = '<root>';
      firstColumn.children.add(rootName);
    } else {
      ClassRefElement classRef = new Element.tag("class-ref");
      classRef.ref = isolate.getClassByCid(v.cid);
      classRef.style.alignSelf = 'center';
      firstColumn.children.add(classRef);
    }

    var secondColumn = flexColumns[1];
    secondColumn.style.justifyContent = 'flex-end';
    secondColumn.style.position = 'relative';
    secondColumn.style.alignItems = 'center';
    secondColumn.style.paddingRight = '0.5em';
    secondColumn.text = Utils.formatSize(edge.shallowSize);
  }
}


class MergedEdge {
  final MergedVertex source;
  final MergedVertex target;
  int count = 0;
  int shallowSize = 0;
  int retainedSize = 0;

  MergedEdge(this.source, this.target);
}

class MergedVertex {
  final int cid;
  int instances = 0;
  int shallowSize = 0;
  int retainedSize = 0;

  List<MergedEdge> incomingEdges = new List<MergedEdge>();
  Map<int, MergedEdge> outgoingEdges = new Map<int, MergedEdge>();

  MergedVertex(this.cid);
}


Future<List<MergedVertex>> buildMergedVertices(ObjectGraph graph) async {
  Logger.root.info("Start merge vertices");

  var cidToMergedVertex = {};

  for (var vertex in graph.vertices) {
    var cid = vertex.vmCid;
    MergedVertex source = cidToMergedVertex[cid];
    if (source == null) {
      cidToMergedVertex[cid] = source = new MergedVertex(cid);
    }

    source.instances++;
    source.shallowSize += (vertex.shallowSize == null ? 0 : vertex.shallowSize);

    for (var vertex2 in vertex.successors) {
      var cid2 = vertex2.vmCid;
      MergedEdge edge = source.outgoingEdges[cid2];
      if (edge == null) {
        MergedVertex target = cidToMergedVertex[cid2];
        if (target == null) {
          cidToMergedVertex[cid2] = target = new MergedVertex(cid2);
        }
        edge = new MergedEdge(source, target);
        source.outgoingEdges[cid2] = edge;
        target.incomingEdges.add(edge);
      }
      edge.count++;
      // An over-estimate if there are multiple references to the same object.
      edge.shallowSize += vertex2.shallowSize == null ? 0 : vertex2.shallowSize;
    }
  }

  Logger.root.info("End merge vertices");

  return cidToMergedVertex.values.toList();
}

@CustomTag('heap-snapshot')
class HeapSnapshotElement extends ObservatoryElement {
  @published Isolate isolate;
  @observable HeapSnapshot snapshot;

  @published String state = 'Requested';
  @published String analysisSelector = 'DominatorTree';

  HeapSnapshotElement.created() : super.created();

  void analysisSelectorChanged(oldValue) {
    _update();
  }

  void isolateChanged(oldValue) {
    if (isolate == null) return;

    if (isolate.latestSnapshot == null) {
      _getHeapSnapshot();
    } else {
      snapshot = isolate.latestSnapshot;
      state = 'Loaded';
      _update();
    }
  }

  Future refresh() {
    return _getHeapSnapshot();
  }

  Future _getHeapSnapshot() {
    var completer = new Completer();
    state = "Requesting heap snapshot...";
    isolate.getClassRefs();

    bool collectGarbage =
        app.locationManager.getBoolParameter('collectGarbage', true);

    var stopwatch = new Stopwatch()..start();
    isolate.fetchHeapSnapshot(collectGarbage).listen((event) {
      if (event is String) {
        print("${stopwatch.elapsedMilliseconds} $event");
        state = event;
      } else if (event is HeapSnapshot) {
        snapshot = event;
        state = 'Loaded';
        completer.complete(snapshot);
        _update();
      } else {
        throw "Unexpected event $event";
      }
    });
    return completer.future;
  }

  void _update() {
    if (snapshot == null) {
      return;
    }

    switch(analysisSelector) {
    case 'DominatorTree':
      _buildDominatorTree();
      break;
    case 'MergeByClass':
      _buildMergedVertices();
      break;
    }
  }

  void _buildDominatorTree() {
    var tableBody = shadowRoot.querySelector('#treeBody');
    var tree = new TableTree(tableBody, 2);
    var rootRow =
        new DominatorTreeRow(tree, null, snapshot.graph.root, snapshot);
    tree.initialize(rootRow);
    return;
  }

  void _buildMergedVertices() {
    state = 'Grouping...';
    var tableBody = shadowRoot.querySelector('#treeBody');
    var tree = new TableTree(tableBody, 2);
    tableBody.children.clear();

    new Future.delayed(const Duration(milliseconds: 500), () {
      buildMergedVertices(snapshot.graph).then((vertices) {
        state = 'Loaded';
        var rootRow = new MergedVerticesRow(tree, null, isolate, vertices);
        tree.initialize(rootRow);
      });
    });
  }
}
