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

var mercury = require('mercury');
var insertCss = require('insert-css');

var methodNameToVarHashKey = require('./methodNameToVarHashKey');

var displayServerDetails = require('./display-server-details');

var methodForm = require('../method-form');
var FieldItem = require('../field-item');
var ErrorBox = require('../../../error/error-box');

var css = require('./index.css');
var h = mercury.h;

module.exports = create;
module.exports.render = render;
module.exports.displayServerDetails = displayServerDetails;

/*
 * ServerDetails component provides user interfaces for displaying details for
 * a server such is its objectAddresses, signature, remote blessings, etc..
 */
function create() {
  var state = mercury.varhash({

    /*
     * namespace item to display details for.
     * @see services/namespace/item
     * @type {namespaceitem}
     */
    item: mercury.value(null),

    /*
     * Name of the item.
     * @type {string}
     */
    itemName: mercury.value(''),

    /*
     * Any fatal error while getting the details.
     * Note: will be displayed to user.
     * @type Error
     */
    error: mercury.value(null),

    /*
     * remoteBlessings for the item. []string
     * @type {[]string}
     */
    remoteBlessings: mercury.value(null),

    /*
     * signature for the item. []interface
     * @see services/namespace/interface-util
     * @type {vanadium.vdl.signature}
     */
    signature: mercury.value(null),

    /*
     * An associative array from item names to method outputs.
     * The outputs are in RPC call-order and store render information.
     * @type {map[string]Array<Object>}
     */
    methodOutputs: mercury.varhash(),

    /*
     * Each method form corresponds to an interface in the signature. It is a
     * map from method names to the relevant state used in the method-form
     * component.
     * @type {[]map[string]mercury.struct}
     */
    methodForms: mercury.array([]),

    /*
     * Each method form could be open or closed. All start out open, except
     * for __Reserved, which is explicitly set to closed.
     * @type {[]boolean}
     */
    methodFormsOpen: mercury.array([]),

    /*
     * Whether a loading indicator should be displayed instead of content
     * @type {mercury.value<boolean>}
     */
    showLoadingIndicator: mercury.value(false),

    /*
     * Whether item is bookmarked
     * @type {mercury.value<boolean>}
     */
    isBookmarked: mercury.value(false),

    /*
     * List of objectAddresses for the name.
     * @type {mercury.array<string>}
     */
    objectAddresses: mercury.array([])
  });

  var events = mercury.input([
    'methodForms',
    'toggleMethodForm',
    'toast'
  ]);

  wireUpEvents(state, events);

  // events.methodForms is []events; the index order matches state.methodForms
  // and state.methodFormsOpen.
  events.methodForms = [];

  return {
    state: state,
    events: events
  };
}

/*
 * Render the server details page.
 */
function render(state, events, browseState, navEvents) {
  insertCss(css);
  var content = [];

  // Details can only be shown if there is an item.
  if (state.item) {
    var detailsContent = renderDetailsContent(state, events);
    content.push(detailsContent);
  }

  // The method forms can only be shown under these conditions.
  if (state.item && state.item.hasServer && state.signature) {
    var methodsContent = renderMethodsContent(state, events);
    content.push(methodsContent);
  }

  // Show any errors from getting the details
  if (state.error) {
    var errorTitle = 'Unable to connect to ' + state.itemName;
    content.push(ErrorBox.render(errorTitle, state.error.toString()));
  }

  // Show the loading indicator if it's available.
  if (state.showLoadingIndicator) {
    content.push(h('paper-spinner', {
      attributes: {
        'active': true,
        'aria-label': 'Loading'
      }
    }));
  }

  return content;
}

/*
 * Renders details about the current service object.
 * Assumes that there is a state.item
 * Note: Currently renders in the same tab as renderMethodsContent.
 */
function renderDetailsContent(state, events) {
  var displayItems = [
    renderNameField(state)
  ];
  if (state.item.hasServer) {
    displayItems.push(renderObjectAddressesFieldItem(state));
    if (state.remoteBlessings) {
      displayItems.push(renderRemoteBlessingsFieldItem(state));
    }
  }
  return [
    h('div', displayItems)
  ];
}

/*
 * Renders the ObjectAddresses Field Item, a simple listing of the server's
 * objectAddresses.
 */
function renderObjectAddressesFieldItem(state) {
  var objectAddressDivs;
  if (!state.objectAddresses || state.objectAddresses.length === 0) {
    objectAddressDivs = [
      h('div', h('span', 'No Object Addresses Found'))
    ];
  } else {
    // Show 1 div per server objectAddress.
    objectAddressDivs = state.objectAddresses.map(function(objectAddress) {
      return h('div', h('span', objectAddress));
    });
  }
  return FieldItem.render('Service Object Addresses', h('div', {
    attributes: {
      'vertical': true,
      'layout': true
    }
  }, objectAddressDivs));
}

/*
 * Renders the Full Name field
 */
function renderNameField(state) {
  return FieldItem.render('Full Name', (state.itemName || '<Home>'));
}

/*
 * Renders the Remote Blessings Field Item, a list of the server's blessings.
 * Does not appear until the data has been fetched.
 */
function renderRemoteBlessingsFieldItem(state) {
  var remoteBlessings = state.remoteBlessings;
  var blessingDivs;
  if (remoteBlessings.length === 0) {
    blessingDivs = [
      h('div', h('span', 'No blessings found'))
    ];
  } else {
    // Show 1 div per blessing.
    blessingDivs = remoteBlessings.map(function(blessing) {
      return h('div', h('span', blessing));
    });
  }
  return FieldItem.render('Remote Blessings', h('div', {
    attributes: {
      'vertical': true,
      'layout': true
    }
  }, blessingDivs));
}

/*
 * Renders the method signature forms and the RPC output area.
 * Does not appear until the data has been fetched.
 */
function renderMethodsContent(state, events) {
  var sig = state.signature;
  if (!sig || sig.size === 0) {
    return FieldItem.render('Methods',
      h('div', h('span', 'No method signature')));
  }

  // Render each interface and an output region.
  var content = state.signature.map(function(interface, interfaceIndex) {
    var label = interface.pkgPath + '.' + interface.name;
    var content;
    var open = state.methodFormsOpen[interfaceIndex];
    var options = {
      labelTooltip: interface.doc,
      collapsed: !open,
      callback: events.toggleMethodForm.bind(null, {
        index: interfaceIndex,
        value: !open
      })
    };
    if (!open) {
      content = h('span');
    } else {
      content = renderMethodInterface(state, events, interfaceIndex);
    }
    return FieldItem.render(label, content, options);
  });
  content.push(FieldItem.render('Output', renderMethodOutput(state)));

  return h('div', content);
}

/*
 * Renders each method signature belonging to one of the interfaces of the
 * service. Each form allows RPCs to be made to the associated service.
 */
function renderMethodInterface(state, events, interfaceIndex) {
  var methods = [];

  // Render all the methods in alphabetical order.
  // ES6 Map iterates in the order values were added, so we must sort them.
  var methodNames = [];
  state.signature[interfaceIndex].methods.forEach(
    function(methodData) {
      methodNames.push(methodData.name);
    }
  );
  methodNames.sort().forEach(function(methodName) {
    var methodKey = methodNameToVarHashKey(methodName);
    methods.push(methodForm.render(
      state.methodForms[interfaceIndex][methodKey],
      events.methodForms[interfaceIndex][methodKey]
    ));
  });

  return h('div', methods); // Note: allows 0 method signatures
}

/*
 * Renders the method outputs received by the current service object.
 * Prints each output received in reverse order; most recent is on top.
 */
function renderMethodOutput(state) {
  var outputs = state.methodOutputs[state.item.objectName];
  if (outputs === undefined) {
    return h('div.method-output', h('span', 'No method output'));
  }
  var outputRows = [h('tr', [
    h('th', '#'),
    h('th', 'Method'),
    h('th', 'Output')
  ])];
  for (var i = outputs.length - 1; i >= 0; i--) {
    var output = outputs[i];
    if (output.shouldShow) {
      outputRows.push(
        h('tr', [
          h('td', {
            'scope': 'row'
          }, '' + (i + 1)),
          h('td', h('pre', output.method)),
          h('td', h('pre', output.result))
        ])
      );
    }
  }

  var outputTable = h('table', {
    attributes: {
      'summary': 'Table showing the outputs of methods run on' +
        'the service. The results are shown in reverse order.'
    }
  }, outputRows);
  return h('div.method-output', outputTable);
}

// Wire up events that we know how to handle
function wireUpEvents(state, events) {
  events.toggleMethodForm(function(data) {
    state.methodFormsOpen.put(data.index, data.value);
  });
}