// Copyright (c) 2013 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('policy', function() {

  /**
   * A hack to check if we are displaying the mobile version of this page by
   * checking if the first column is hidden.
   * @return {boolean} True if this is the mobile version.
   */
  var isMobilePage = function() {
    return document.defaultView.getComputedStyle(document.querySelector(
        '.scope-column')).display == 'none';
  }

  /**
   * A box that shows the status of cloud policy for a device or user.
   * @constructor
   * @extends {HTMLFieldSetElement}
   */
  var StatusBox = cr.ui.define(function() {
    var node = $('status-box-template').cloneNode(true);
    node.removeAttribute('id');
    return node;
  });

  StatusBox.prototype = {
    // Set up the prototype chain.
    __proto__: HTMLFieldSetElement.prototype,

    /**
     * Initialization function for the cr.ui framework.
     */
    decorate: function() {
    },

    /**
     * Populate the box with the given cloud policy status.
     * @param {string} scope The policy scope, either "device" or "user".
     * @param {Object} status Dictionary with information about the status.
     */
    initialize: function(scope, status) {
      if (scope == 'device') {
        // For device policy, set the appropriate title and populate the topmost
        // status item with the domain the device is enrolled into.
        this.querySelector('.legend').textContent =
            loadTimeData.getString('statusDevice');
        var domain = this.querySelector('.domain');
        domain.textContent = status.domain;
        domain.parentElement.hidden = false;
      } else {
        // For user policy, set the appropriate title and populate the topmost
        // status item with the username that policies apply to.
        this.querySelector('.legend').textContent =
            loadTimeData.getString('statusUser');
        // Populate the topmost item with the username.
        var username = this.querySelector('.username');
        username.textContent = status.username;
        username.parentElement.hidden = false;
      }
      // Populate all remaining items.
      this.querySelector('.client-id').textContent = status.clientId || '';
      this.querySelector('.time-since-last-refresh').textContent =
          status.timeSinceLastRefresh || '';
      this.querySelector('.refresh-interval').textContent =
          status.refreshInterval || '';
      this.querySelector('.status').textContent = status.status || '';
    },
  };

  /**
   * A single policy's entry in the policy table.
   * @constructor
   * @extends {HTMLTableSectionElement}
   */
  var Policy = cr.ui.define(function() {
    var node = $('policy-template').cloneNode(true);
    node.removeAttribute('id');
    return node;
  });

  Policy.prototype = {
    // Set up the prototype chain.
    __proto__: HTMLTableSectionElement.prototype,

    /**
     * Initialization function for the cr.ui framework.
     */
    decorate: function() {
      this.updateToggleExpandedValueText_();
      this.querySelector('.toggle-expanded-value').addEventListener(
          'click', this.toggleExpandedValue_.bind(this));
    },

    /**
     * Populate the table columns with information about the policy name, value
     * and status.
     * @param {string} name The policy name.
     * @param {Object} value Dictionary with information about the policy value.
     * @param {boolean} unknown Whether the policy name is not recognized.
     */
    initialize: function(name, value, unknown) {
      this.name = name;
      this.unset = !value;

      // Populate the name column.
      this.querySelector('.name').textContent = name;

      // Populate the remaining columns with policy scope, level and value if a
      // value has been set. Otherwise, leave them blank.
      if (value) {
        this.querySelector('.scope').textContent =
            loadTimeData.getString(value.scope == 'user' ?
                'scopeUser' : 'scopeDevice');
        this.querySelector('.level').textContent =
            loadTimeData.getString(value.level == 'recommended' ?
                'levelRecommended' : 'levelMandatory');
        this.querySelector('.value').textContent = value.value;
        this.querySelector('.expanded-value').textContent = value.value;
      }

      // Populate the status column.
      var status;
      if (!value) {
        // If the policy value has not been set, show an error message.
        status = loadTimeData.getString('unset');
      } else if (unknown) {
        // If the policy name is not recognized, show an error message.
        status = loadTimeData.getString('unknown');
      } else if (value.error) {
        // If an error occurred while parsing the policy value, show the error
        // message.
        status = value.error;
      } else {
        // Otherwise, indicate that the policy value was parsed correctly.
        status = loadTimeData.getString('ok');
      }
      this.querySelector('.status').textContent = status;

      if (isMobilePage()) {
        // The number of columns which are hidden by the css file for the mobile
        // (Android) version of this page.
        /** @const */ var HIDDEN_COLUMNS_IN_MOBILE_VERSION = 2;

        var expandedValue = this.querySelector('.expanded-value');
        expandedValue.setAttribute('colspan',
            expandedValue.colSpan - HIDDEN_COLUMNS_IN_MOBILE_VERSION);
      }
    },

    /**
     * Check the table columns for overflow. Most columns are automatically
     * elided when overflow occurs. The only action required is to add a tooltip
     * that shows the complete content. The value column is an exception. If
     * overflow occurs here, the contents is replaced with a link that toggles
     * the visibility of an additional row containing the complete value.
     */
    checkOverflow: function() {
      // Set a tooltip on all overflowed columns except the value column.
      var divs = this.querySelectorAll('div.elide');
      for (var i = 0; i < divs.length; i++) {
        var div = divs[i];
        div.title = div.offsetWidth < div.scrollWidth ? div.textContent : '';
      }

      // Cache the width of the value column's contents when it is first shown.
      // This is required to be able to check whether the contents would still
      // overflow the column once it has been hidden and replaced by a link.
      var valueContainer = this.querySelector('.value-container');
      if (valueContainer.valueWidth == undefined) {
        valueContainer.valueWidth =
            valueContainer.querySelector('.value').offsetWidth;
      }

      // Determine whether the contents of the value column overflows. The
      // visibility of the contents, replacement link and additional row
      // containing the complete value that depend on this are handled by CSS.
      if (valueContainer.offsetWidth < valueContainer.valueWidth)
        this.classList.add('has-overflowed-value');
      else
        this.classList.remove('has-overflowed-value');
    },

    /**
     * Update the text of the link that toggles the visibility of an additional
     * row containing the complete policy value, depending on the toggle state.
     * @private
     */
    updateToggleExpandedValueText_: function(event) {
      this.querySelector('.toggle-expanded-value').textContent =
          loadTimeData.getString(
              this.classList.contains('show-overflowed-value') ?
                  'hideExpandedValue' : 'showExpandedValue');
    },

    /**
     * Toggle the visibility of an additional row containing the complete policy
     * value.
     * @private
     */
    toggleExpandedValue_: function() {
      this.classList.toggle('show-overflowed-value');
      this.updateToggleExpandedValueText_();
    },
  };

  /**
   * A table of policies and their values.
   * @constructor
   * @extends {HTMLTableSectionElement}
   */
  var PolicyTable = cr.ui.define('tbody');

  PolicyTable.prototype = {
    // Set up the prototype chain.
    __proto__: HTMLTableSectionElement.prototype,

    /**
     * Initialization function for the cr.ui framework.
     */
    decorate: function() {
      this.policies_ = {};
      this.filterPattern_ = '';
      window.addEventListener('resize', this.checkOverflow_.bind(this));
    },

    /**
     * Initialize the list of all known policies.
     * @param {Object} names Dictionary containing all known policy names.
     */
    setPolicyNames: function(names) {
      this.policies_ = names;
      this.setPolicyValues({});
    },

    /**
     * Populate the table with the currently set policy values and any errors
     * detected while parsing these.
     * @param {Object} values Dictionary containing the current policy values.
     */
    setPolicyValues: function(values) {
      // Remove all policies from the table.
      var policies = this.getElementsByTagName('tbody');
      while (policies.length > 0)
        this.removeChild(policies.item(0));

      // First, add known policies whose value is currently set.
      var unset = [];
      for (var name in this.policies_) {
        if (name in values)
          this.setPolicyValue_(name, values[name], false);
        else
          unset.push(name);
      }

      // Second, add policies whose value is currently set but whose name is not
      // recognized.
      for (var name in values) {
        if (!(name in this.policies_))
          this.setPolicyValue_(name, values[name], true);
      }

      // Finally, add known policies whose value is not currently set.
      for (var i = 0; i < unset.length; i++)
        this.setPolicyValue_(unset[i], undefined, false);

      // Filter the policies.
      this.filter();
    },

    /**
     * Set the filter pattern. Only policies whose name contains |pattern| are
     * shown in the policy table. The filter is case insensitive. It can be
     * disabled by setting |pattern| to an empty string.
     * @param {string} pattern The filter pattern.
     */
    setFilterPattern: function(pattern) {
      this.filterPattern_ = pattern.toLowerCase();
      this.filter();
    },

    /**
     * Filter policies. Only policies whose name contains the filter pattern are
     * shown in the table. Furthermore, policies whose value is not currently
     * set are only shown if the corresponding checkbox is checked.
     */
    filter: function() {
      var showUnset = $('show-unset').checked;
      var policies = this.getElementsByTagName('tbody');
      for (var i = 0; i < policies.length; i++) {
        var policy = policies[i];
        policy.hidden =
            policy.unset && !showUnset ||
            policy.name.toLowerCase().indexOf(this.filterPattern_) == -1;
      }
      if (this.querySelector('tbody:not([hidden])'))
        this.parentElement.classList.remove('empty');
      else
        this.parentElement.classList.add('empty');
      setTimeout(this.checkOverflow_.bind(this), 0);
    },

    /**
     * Check the table columns for overflow.
     * @private
     */
    checkOverflow_: function() {
      var policies = this.getElementsByTagName('tbody');
      for (var i = 0; i < policies.length; i++) {
        if (!policies[i].hidden)
          policies[i].checkOverflow();
      }
    },

    /**
     * Add a policy with the given |name| and |value| to the table.
     * @param {string} name The policy name.
     * @param {Object} value Dictionary with information about the policy value.
     * @param {boolean} unknown Whether the policy name is not recoginzed.
     * @private
     */
    setPolicyValue_: function(name, value, unknown) {
      var policy = new Policy;
      policy.initialize(name, value, unknown);
      this.appendChild(policy);
    },
  };

  /**
   * A singelton object that handles communication between browser and WebUI.
   * @constructor
   */
  function Page() {
  }

  // Make Page a singleton.
  cr.addSingletonGetter(Page);

  /**
   * Provide a list of all known policies to the UI. Called by the browser on
   * page load.
   * @param {Object} names Dictionary containing all known policy names.
   */
  Page.setPolicyNames = function(names) {
    var page = this.getInstance();

    // Clear all policy tables.
    page.mainSection.innerHTML = '';
    page.policyTables = {};

    // Create tables and set known policy names for Chrome and extensions.
    if (names.hasOwnProperty('chromePolicyNames')) {
      var table = page.appendNewTable('chrome', 'Chrome policies', '');
      table.setPolicyNames(names.chromePolicyNames);
    }

    if (names.hasOwnProperty('extensionPolicyNames')) {
      for (var ext in names.extensionPolicyNames) {
        var table = page.appendNewTable('extension-' + ext,
            names.extensionPolicyNames[ext].name, 'ID: ' + ext);
        table.setPolicyNames(names.extensionPolicyNames[ext].policyNames);
      }
    }
  };

  /**
   * Provide a list of the currently set policy values and any errors detected
   * while parsing these to the UI. Called by the browser on page load and
   * whenever policy values change.
   * @param {Object} values Dictionary containing the current policy values.
   */
  Page.setPolicyValues = function(values) {
    var page = this.getInstance();
    if (values.hasOwnProperty('chromePolicies')) {
      var table = page.policyTables['chrome'];
      table.setPolicyValues(values.chromePolicies);
    }

    if (values.hasOwnProperty('extensionPolicies')) {
      for (var extensionId in values.extensionPolicies) {
        var table = page.policyTables['extension-' + extensionId];
        if (table)
          table.setPolicyValues(values.extensionPolicies[extensionId]);
      }
    }
  };

  /**
   * Provide the current cloud policy status to the UI. Called by the browser on
   * page load if cloud policy is present and whenever the status changes.
   * @param {Object} status Dictionary containing the current policy status.
   */
  Page.setStatus = function(status) {
    this.getInstance().setStatus(status);
  };

  /**
   * Notify the UI that a request to reload policy values has completed. Called
   * by the browser after a request to reload policy has been sent by the UI.
   */
  Page.reloadPoliciesDone = function() {
    this.getInstance().reloadPoliciesDone();
  };

  Page.prototype = {
    /**
     * Main initialization function. Called by the browser on page load.
     */
    initialize: function() {
      uber.onContentFrameLoaded();
      cr.ui.FocusOutlineManager.forDocument(document);

      this.mainSection = $('main-section');
      this.policyTables = {};

      // Place the initial focus on the filter input field.
      $('filter').focus();

      var self = this;
      $('filter').onsearch = function(event) {
        for (policyTable in self.policyTables) {
          self.policyTables[policyTable].setFilterPattern(this.value);
        }
      };
      $('reload-policies').onclick = function(event) {
        this.disabled = true;
        chrome.send('reloadPolicies');
      };

      $('show-unset').onchange = function() {
        for (policyTable in self.policyTables) {
          self.policyTables[policyTable].filter();
        }
      };

      // Notify the browser that the page has loaded, causing it to send the
      // list of all known policies, the current policy values and the cloud
      // policy status.
      chrome.send('initialized');
    },

   /**
     * Creates a new policy table section, adds the section to the page,
     * and returns the new table from that section.
     * @param {string} id The key for storing the new table in policyTables.
     * @param {string} label_title Title for this policy table.
     * @param {string} label_content Description for the policy table.
     * @return {Element} The newly created table.
     */
    appendNewTable: function(id, label_title, label_content) {
      var newSection = this.createPolicyTableSection(id, label_title,
          label_content);
      this.mainSection.appendChild(newSection);
      return this.policyTables[id];
    },

    /**
     * Creates a new section containing a title, description and table of
     * policies.
     * @param {id} id The key for storing the new table in policyTables.
     * @param {string} label_title Title for this policy table.
     * @param {string} label_content Description for the policy table.
     * @return {Element} The newly created section.
     */
    createPolicyTableSection: function(id, label_title, label_content) {
      var section = document.createElement('section');
      section.setAttribute('class', 'policy-table-section');

      // Add title and description.
      var title = window.document.createElement('h3');
      title.textContent = label_title;
      section.appendChild(title);

      if (label_content) {
        var description = window.document.createElement('div');
        description.classList.add('table-description');
        description.textContent = label_content;
        section.appendChild(description);
      }

      // Add 'No Policies Set' element.
      var noPolicies = window.document.createElement('div');
      noPolicies.classList.add('no-policies-set');
      noPolicies.textContent = loadTimeData.getString('noPoliciesSet');
      section.appendChild(noPolicies);

      // Add table of policies.
      var newTable = this.createPolicyTable();
      this.policyTables[id] = newTable;
      section.appendChild(newTable);

      return section;
    },

    /**
     * Creates a new table for displaying policies.
     * @return {Element} The newly created table.
     */
    createPolicyTable: function() {
      var newTable = window.document.createElement('table');
      var tableHead = window.document.createElement('thead');
      var tableRow = window.document.createElement('tr');
      var tableHeadings = ['Scope', 'Level', 'Name', 'Value', 'Status'];
      for (var i = 0; i < tableHeadings.length; i++) {
        var tableHeader = window.document.createElement('th');
        tableHeader.classList.add(tableHeadings[i].toLowerCase() + '-column');
        tableHeader.textContent = loadTimeData.getString('header' +
                                                         tableHeadings[i]);
        tableRow.appendChild(tableHeader);
      }
      tableHead.appendChild(tableRow);
      newTable.appendChild(tableHead);
      cr.ui.decorate(newTable, PolicyTable);
      return newTable;
    },

    /**
     * Update the status section of the page to show the current cloud policy
     * status.
     * @param {Object} status Dictionary containing the current policy status.
     */
    setStatus: function(status) {
      // Remove any existing status boxes.
      var container = $('status-box-container');
      while (container.firstChild)
        container.removeChild(container.firstChild);
      // Hide the status section.
      var section = $('status-section');
      section.hidden = true;

      // Add a status box for each scope that has a cloud policy status.
      for (var scope in status) {
        var box = new StatusBox;
        box.initialize(scope, status[scope]);
        container.appendChild(box);
        // Show the status section.
        section.hidden = false;
      }
    },

    /**
     * Re-enable the reload policies button when the previous request to reload
     * policies values has completed.
     */
    reloadPoliciesDone: function() {
      $('reload-policies').disabled = false;
    },
  };

  return {
    Page: Page
  };
});

// Have the main initialization function be called when the page finishes
// loading.
document.addEventListener(
    'DOMContentLoaded',
    policy.Page.getInstance().initialize.bind(policy.Page.getInstance()));
