// Copyright (c) 2013, 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 isolate_view_element;

import 'dart:async';
import 'observatory_element.dart';
import 'package:observatory/app.dart';
import 'package:observatory/service.dart';
import 'package:polymer/polymer.dart';

class TagProfileChart {
  var _table = new DataTable();
  var _chart;

  void update(TagProfile tagProfile) {
    if (_table.columns == 0) {
      // Initialize.
      _table.addColumn('string', 'Time');
      for (var tagName in tagProfile.names) {
        if (tagName == 'Idle') {
          // Skip Idle tag.
          continue;
        }
        _table.addColumn('number', tagName);
      }
    }
    _table.clearRows();
    var idleIndex = tagProfile.names.indexOf('Idle');
    assert(idleIndex != -1);
    var t = tagProfile.updatedAtSeconds;
    for (var i = 0; i < tagProfile.snapshots.length; i++) {
      var snapshotTime = tagProfile.snapshots[i].seconds;
      var row = [];
      if (snapshotTime > 0.0) {
        row.add('t ${(snapshotTime - t).toStringAsFixed(2)}');
      } else {
        row.add('');
      }
      var sum = tagProfile.snapshots[i].sum;
      if (sum == 0) {
        for (var j = 0; j < tagProfile.snapshots[i].counters.length; j++) {
          if (j == idleIndex) {
            // Skip idle.
            continue;
          }
          row.add(0);
        }
     } else {
       for (var j = 0; j < tagProfile.snapshots[i].counters.length; j++) {
         if (j == idleIndex) {
           // Skip idle.
           continue;
         }
         var percentage = tagProfile.snapshots[i].counters[j] / sum * 100.0;
         row.add(percentage.toInt());
       }
     }
     _table.addRow(row);
    }
  }

  void draw(var element) {
    if (_chart == null) {
      assert(element != null);
      _chart = new Chart('SteppedAreaChart', element);
      _chart.options['isStacked'] = true;
      _chart.options['connectSteps'] = false;
      _chart.options['vAxis'] = {
        'minValue': 0.0,
        'maxValue': 100.0,
      };
    }
    _chart.draw(_table);
  }
}

@CustomTag('isolate-view')
class IsolateViewElement extends ObservatoryElement {
  @published Isolate isolate;
  Timer _updateTimer;
  TagProfileChart tagProfileChart = new TagProfileChart();
  IsolateViewElement.created() : super.created();

  Future<ServiceObject> eval(String expression) {
    return isolate.eval(isolate.rootLib, expression);
  }

  void _updateTagProfile() {
    isolate.updateTagProfile().then((tagProfile) {
      tagProfileChart.update(tagProfile);
      _drawTagProfileChart();
      if (_updateTimer != null) {
        // Start the timer again.
        _updateTimer = new Timer(new Duration(seconds: 1), _updateTagProfile);
      }
    });
  }

  @override
  void attached() {
    super.attached();
    // Start a timer to update the isolate summary once a second.
    _updateTimer = new Timer(new Duration(seconds: 1), _updateTagProfile);
  }

  @override
  void detached() {
    super.detached();
    if (_updateTimer != null) {
      _updateTimer.cancel();
      _updateTimer = null;
    }
  }

  void _drawTagProfileChart() {
    var element = shadowRoot.querySelector('#tagProfileChart');
    if (element != null) {
      tagProfileChart.draw(element);
    }
  }

  void refresh(var done) {
    isolate.reload().whenComplete(done);
  }

  void refreshCoverage(var done) {
    isolate.refreshCoverage().whenComplete(done);
  }

  Future pause(_) {
    return isolate.pause().then((result) {
        // TODO(turnidge): Instead of asserting here, handle errors
        // properly.
        assert(result.type == 'Success');
        return isolate.reload();
      });
  }

  Future resume(_) {
    return isolate.resume().then((result) {
        // TODO(turnidge): Instead of asserting here, handle errors
        // properly.
        assert(result.type == 'Success');
        return isolate.reload();
      });
  }
}
