// Copyright (c) 2012 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('cert_viewer', function() {
  'use strict';

  /**
   * Initialize the certificate viewer dialog by wiring up the close button,
   * substituting in translated strings and requesting certificate details.
   */
  function initialize() {
    cr.ui.decorate('tabbox', cr.ui.TabBox);

    const args = JSON.parse(chrome.getVariableValue('dialogArguments'));
    getCertificateInfo(args);

    /**
     * Initialize the second tab's contents.
     * This is a 'oneShot' function, meaning it will only be invoked once,
     * no matter how many times it is called.  This is done for unit-testing
     * purposes in case a test needs to initialize the tab before the timer
     * fires.
     */
    const initializeDetailTab = oneShot(function() {
      initializeTree($('hierarchy'), showCertificateFields);
      initializeTree($('cert-fields'), showCertificateFieldValue);
      createCertificateHierarchy(args.hierarchy);
    });

    // The second tab's contents aren't visible on startup, so we can
    // shorten startup by not populating those controls until after we
    // have had a chance to draw the visible controls the first time.
    // The value of 200ms is quick enough that the user couldn't open the
    // tab in that time but long enough to allow the first tab to draw on
    // even the slowest machine.
    setTimeout(initializeDetailTab, 200);

    $('tabbox').addEventListener('selectedChange', function f(e) {
      $('tabbox').removeEventListener('selectedChange', f);
      initializeDetailTab();
    }, true);

    stripGtkAccessorKeys();

    $('export').onclick = exportCertificate;
  }

  /**
   * Decorate a function so that it can only be invoked once.
   */
  function oneShot(fn) {
    let fired = false;
    return function() {
      if (fired) {
        return;
      }
      fired = true;
      fn();
    };
  }

  /**
   * Initialize a cr.ui.Tree object from a given element using the specified
   * change handler.
   * @param {HTMLElement} tree The HTMLElement to style as a tree.
   * @param {function()} handler Function to call when a node is selected.
   */
  function initializeTree(tree, handler) {
    cr.ui.decorate(tree, cr.ui.Tree);
    tree.detail = {payload: {}, children: {}};
    tree.addEventListener('change', handler);
  }

  /**
   * The tab name strings in the languages file have accessor keys indicated
   * by a preceding & sign. Strip these out for now.
   * TODO(flackr) These accessor keys could be implemented with Javascript or
   *     translated strings could be added / modified to remove the & sign.
   */
  function stripGtkAccessorKeys() {
    // Copy all the tab labels into an array.
    const nodes = Array.prototype.slice.call($('tabs').childNodes, 0);
    nodes.push($('export'));
    for (let i = 0; i < nodes.length; i++) {
      nodes[i].textContent = nodes[i].textContent.replace('&', '');
    }
  }

  /**
   * Expand all nodes of the given tree object.
   * @param {cr.ui.Tree} tree The tree object to expand all nodes on.
   */
  function revealTree(tree) {
    tree.expanded = true;
    for (const key in tree.detail.children) {
      revealTree(tree.detail.children[key]);
    }
  }

  /**
   * This function is called from certificate_viewer_ui.cc with the certificate
   * information. Display all returned information to the user.
   * @param {Object} certInfo Certificate information in named fields.
   */
  function getCertificateInfo(certInfo) {
    for (const key in certInfo.general) {
      $(key).textContent = certInfo.general[key];
    }
  }

  /**
   * This function populates the certificate hierarchy.
   * @param {Object} hierarchy A dictionary containing the hierarchy.
   */
  function createCertificateHierarchy(hierarchy) {
    const treeItem = $('hierarchy');
    const root = constructTree(hierarchy[0]);
    treeItem.detail.children['root'] = root;
    treeItem.add(root);

    // Select the last item in the hierarchy (really we have a list here - each
    // node has at most one child).  This will reveal the parent nodes and
    // populate the fields view.
    let last = root;
    while (last.detail.children && last.detail.children[0]) {
      last = last.detail.children[0];
    }
    last.selected = true;
  }

  /**
   * Constructs a cr.ui.TreeItem corresponding to the passed in tree
   * @param {Object} tree Dictionary describing the tree structure.
   * @return {cr.ui.TreeItem} Tree node corresponding to the input dictionary.
   */
  function constructTree(tree) {
    const treeItem = new cr.ui.TreeItem({
      label: tree.label,
      detail: {payload: tree.payload ? tree.payload : {}, children: {}}
    });
    if (tree.children) {
      for (let i = 0; i < tree.children.length; i++) {
        treeItem.add(
            treeItem.detail.children[i] = constructTree(tree.children[i]));
      }
    }
    return treeItem;
  }

  /**
   * Clear any previous certificate fields in the tree.
   */
  function clearCertificateFields() {
    const treeItem = $('cert-fields');
    for (const key in treeItem.detail.children) {
      treeItem.remove(treeItem.detail.children[key]);
      delete treeItem.detail.children[key];
    }
  }

  /**
   * Request certificate fields for the selected certificate in the hierarchy.
   */
  function showCertificateFields() {
    clearCertificateFields();
    const item = $('hierarchy').selectedItem;
    if (item && item.detail.payload.index !== undefined) {
      chrome.send('requestCertificateFields', [item.detail.payload.index]);
    }
  }

  /**
   * Show the returned certificate fields for the selected certificate.
   * @param {Object} certFields A dictionary containing the fields tree
   *     structure.
   */
  function getCertificateFields(certFields) {
    clearCertificateFields();
    const treeItem = $('cert-fields');
    treeItem.add(
        treeItem.detail.children['root'] = constructTree(certFields[0]));
    revealTree(treeItem);
    // Ensure the list is scrolled to the top by selecting the first item.
    treeItem.children[0].selected = true;
  }

  /**
   * Show certificate field value for a selected certificate field.
   */
  function showCertificateFieldValue() {
    const item = $('cert-fields').selectedItem;
    if (item && item.detail.payload.val) {
      $('cert-field-value').textContent = item.detail.payload.val;
    } else {
      $('cert-field-value').textContent = '';
    }
  }

  /**
   * Export the selected certificate.
   */
  function exportCertificate() {
    const item = $('hierarchy').selectedItem;
    if (item && item.detail.payload.index !== undefined) {
      chrome.send('exportCertificate', [item.detail.payload.index]);
    }
  }

  return {
    initialize: initialize,
    getCertificateFields: getCertificateFields,
  };
});

document.addEventListener('DOMContentLoaded', cert_viewer.initialize);
