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

cr.define('chrome.invalidations', function() {
  /**
   * Local variable where we maintain a count of the invalidations received
   * and of every ObjectId that has ever been updated (note that this doesn't
   * log any invalidations ocurred prior to opening the about:invalidation
   * page).
   */
  const tableObjects = {};

  /**
   * Local variable that contains the detailed information in an object form.
   * This was done this way as to allow multiple calls to updateDetailedStatus
   * to keep adding new items.
   */
  let cachedDetails = {};

  function quote(str) {
    return '\"' + str + '\"';
  }

  function nowTimeString() {
    return '[' + new Date().getTime() + '] ';
  }

  /**
   * Appends a string to a textarea log.
   * @param {string} logMessage The string to be appended.
   */
  function appendToLog(logMessage) {
    const invalidationsLog = $('invalidations-log');
    invalidationsLog.value += logMessage + '\n';
  }
  /**
   *  Updates the jstemplate with the latest ObjectIds, ordered by registrar.
   */
  function repaintTable() {
    const keys = [];
    for (const key in tableObjects) {
      keys.push(key);
    }
    keys.sort();
    const sortedInvalidations = [];
    for (let i = 0; i < keys.length; i++) {
      sortedInvalidations.push(tableObjects[keys[i]]);
    }
    const wrapped = {objectsidtable: sortedInvalidations};
    jstProcess(new JsEvalContext(wrapped), $('objectsid-table-div'));
  }

  /**
   * Shows the current state of the InvalidatorService.
   * @param {string} newState The string to be displayed and logged.
   * @param {number} lastChangedTime The time in epoch when the state was last
   *     changed.
   */
  function updateInvalidatorState(newState, lastChangedTime) {
    const logMessage = nowTimeString() +
        'Invalidations service state changed to ' + quote(newState);

    appendToLog(logMessage);
    $('invalidations-state').textContent =
        newState + ' (since ' + new Date(lastChangedTime) + ')';
  }

  /**
   * Adds to the log the latest invalidations received
   * @param {!Array<!Object>} allInvalidations The array of ObjectId
   *     that contains the invalidations received by the InvalidatorService.
   */
  function logInvalidations(allInvalidations) {
    for (let i = 0; i < allInvalidations.length; i++) {
      const inv = allInvalidations[i];
      if (inv.hasOwnProperty('objectId')) {
        const logMessage = nowTimeString() +
            'Received Invalidation with type ' + quote(inv.objectId.name) +
            ' version ' +
            quote((inv.isUnknownVersion ? 'Unknown' : inv.version)) +
            ' with payload ' + quote(inv.payload);

        appendToLog(logMessage);
        const isInvalidation = true;
        logToTable(inv, isInvalidation);
      }
    }
    repaintTable();
  }

  /**
   * Marks a change in the table whether a new invalidation has arrived
   * or a new ObjectId is currently being added or updated.
   * @param {!Object} oId The ObjectId being added or updated.
   * @param {!boolean} isInvaldation A flag that says that an invalidation
   *     for this ObjectId has arrived or we just need to add it to the table
   *     as it was just updated its state.
   */
  function logToTable(oId, isInvalidation) {
    const registrar = oId.registrar;
    const name = oId.objectId.name;
    const source = oId.objectId.source;
    const totalCount = oId.objectId.totalCount || 0;
    const key = source + '-' + name;
    const time = new Date();
    const version = oId.isUnknownVersion ? '?' : oId.version;
    let payload = '';
    if (oId.hasOwnProperty('payload')) {
      payload = oId.payload;
    }
    if (!(key in tableObjects)) {
      tableObjects[key] = {
        name: name,
        source: source,
        totalCount: totalCount,
        sessionCount: 0,
        registrar: registrar,
        time: '',
        version: '',
        payload: '',
        type: 'content'
      };
    }
    // Refresh the type to be a content because it might have been
    // greyed out.
    tableObjects[key].type = 'content';
    if (isInvalidation) {
      tableObjects[key].totalCount = tableObjects[key].totalCount + 1;
      tableObjects[key].sessionCount = tableObjects[key].sessionCount + 1;
      tableObjects[key].time = time.toTimeString();
      tableObjects[key].version = version;
      tableObjects[key].payload = payload;
    }
  }

  /**
   * Shows the handlers that are currently registered for invalidations
   * (but might not have objects ids registered yet).
   * @param {!Array<string>} allHandlers An array of Strings that are
   *     the names of all the handlers currently registered in the
   *     InvalidatorService.
   */
  function updateHandlers(allHandlers) {
    const allHandlersFormatted = allHandlers.join(', ');
    $('registered-handlers').textContent = allHandlersFormatted;
    const logMessage = nowTimeString() +
        'InvalidatorHandlers currently registered: ' + allHandlersFormatted;
    appendToLog(logMessage);
  }

  /**
   * Updates the table with the objects ids registered for invalidations
   * @param {string} registrar The name of the owner of the InvalidationHandler
   *     that is registered for invalidations
   * @param {Array of Object} allIds An array of ObjectsIds that are currently
   *     registered for invalidations. It is not differential (as in, whatever
   *     is not registered now but was before, it mean it was taken out the
   *     registered objects)
   */
  function updateIds(registrar, allIds) {
    // Grey out every datatype assigned to this registrar
    // (and reenable them later in case they are still registered).
    for (const key in tableObjects) {
      if (tableObjects[key]['registrar'] === registrar) {
        tableObjects[key].type = 'greyed';
      }
    }
    // Reenable those ObjectsIds still registered with this registrar.
    for (let i = 0; i < allIds.length; i++) {
      const oId = {objectId: allIds[i], registrar: registrar};
      const isInvalidation = false;
      logToTable(oId, isInvalidation);
    }
    repaintTable();
  }

  /**
   * Update the internal status display, merging new detailed information.
   * @param {!Object} newDetails The dictionary containing assorted debugging
   *      details (e.g. Network Channel information).
   */
  function updateDetailedStatus(newDetails) {
    for (const key in newDetails) {
      cachedDetails[key] = newDetails[key];
    }
    $('internal-display').value = JSON.stringify(cachedDetails, null, 2);
  }

  /**
   * Function that notifies the InvalidationsMessageHandler that the UI is
   * ready to receive real-time notifications.
   */
  function onLoadWork() {
    $('request-detailed-status').onclick = function() {
      cachedDetails = {};
      chrome.send('requestDetailedStatus');
    };
    chrome.send('doneLoading');
  }

  return {
    logInvalidations: logInvalidations,
    onLoadWork: onLoadWork,
    updateDetailedStatus: updateDetailedStatus,
    updateHandlers: updateHandlers,
    updateIds: updateIds,
    updateInvalidatorState: updateInvalidatorState,
  };
});

document.addEventListener('DOMContentLoaded', chrome.invalidations.onLoadWork);
