// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

var RECORD_TTL_MS = 10000;


$.widget('mobmonitor.healthDisplay', {
  options: {},

  _create: function() {
    this.element.addClass('health-display');

    // Service status information. The variable serviceHealthStatusInfo
    // is a mapping of the following form:
    //
    //  {serviceName: {lastUpdatedTimestampInMs: lastUpdatedTimestampInMs,
    //                 serviceStatus: serviceStatus}}
    //
    //  Where serviceStatus objects are of the following form:
    //
    //  {serviceName: serviceNameString,
    //   health: boolean,
    //   healthchecks: [
    //      {name: healthCheckName, health: boolean,
    //       description: descriptionString,
    //       actions: [actionNameString]}
    //    ]
    //  }
    this.serviceHealthStatusInfo = {};
  },

  _destroy: function() {
    this.element.removeClass('health-display');
    this.element.empty();
  },

  _setOption: function(key, value) {
    this._super(key, value);
  },

  // Private widget methods.
  // TODO (msartori): Implement crbug.com/520746.
  _updateHealthDisplayServices: function(services) {
    var self = this;

    function _removeService(service) {
      // Remove the UI elements.
      var id = '#' + SERVICE_CONTAINER_PREFIX + service;
      $(id).empty();
      $(id).remove();

      // Remove raw service status info that we are holding.
      delete self.serviceHealthStatusInfo[service];
    }

    function _addService(serviceStatus) {
      // This function is used as a callback to the rpcGetStatus.
      // rpcGetStatus returns a list of service health statuses.
      // In this widget, we add services one at a time, so take
      // the first element.
      serviceStatus = serviceStatus[0];

      // Create the new content for the healthDisplay widget.
      var templateData = jQuery.extend({}, serviceStatus);
      templateData.serviceId = SERVICE_CONTAINER_PREFIX + serviceStatus.service;
      templateData.errors = serviceStatus.healthchecks.filter(function(v) {
        return !v.health;
      });
      templateData.warnings = serviceStatus.healthchecks.filter(function(v) {
        return v.health;
      });

      var healthContainer = renderTemplate('healthstatuscontainer',
                                           templateData);

      // Insert the new container into the display widget.
      $(healthContainer).appendTo(self.element);

      // Maintain alphabetical order in our display.
      self.element.children().sort(function(a, b) {
          return $(a).attr('id') < $(b).attr('id') ? -1 : 1;
      }).appendTo(self.element);

      // Save information to do with this service.
      var curtime = $.now();
      var service = serviceStatus.service;

      self.serviceHealthStatusInfo[service] = {
          lastUpdatedTimestampInMs: curtime,
          serviceStatus: serviceStatus
      };
    }

    // Remove services that are no longer monitored or are stale.
    var now = $.now();

    Object.keys(this.serviceHealthStatusInfo).forEach(
        function(elem, index, array) {
          if ($.inArray(elem, services) < 0 ||
            now > self.serviceHealthStatusInfo[elem].lastUpdatedTimestampInMs +
              RECORD_TTL_MS) {
            _removeService(elem);
          }
    });

    // Get sublist of services to update.
    var updateList =
        $(services).not(Object.keys(this.serviceHealthStatusInfo)).get();

    // Update the services.
    updateList.forEach(function(elem, index, array) {
      rpcGetStatus(elem, _addService);
    });
  },

  // Public widget methods.
  refreshHealthDisplay: function() {
    var self = this;
    rpcGetServiceList(function(services) {
      self._updateHealthDisplayServices(services);
    });
  },

  needsRepair: function(service) {
    var serviceStatus = this.serviceHealthStatusInfo[service].serviceStatus;
    return serviceStatus.health == 'false' ||
        serviceStatus.healthchecks.length > 0;
  },

  markStale: function(service) {
    this.serviceHealthStatusInfo[service].lastUpdatedTimestampInMs = 0;
  },

  getServiceActions: function(service) {
    var actionSet = {};
    var healthchecks =
        this.serviceHealthStatusInfo[service].serviceStatus.healthchecks;

    for (var i = 0; i < healthchecks.length; i++) {
      for (var j = 0; j < healthchecks[i].actions.length; j++) {
        actionSet[healthchecks[i].actions[j]] = true;
      }
    }

    return Object.keys(actionSet);
  }
});
