// 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 _ = require('lodash');
var uuid = require('uuid');

var makeRPC = require('./make-rpc.js');

var arraySet = require('../../../../lib/array-set');
var setMercuryArray = require('../../../../lib/mercury/set-mercury-array');
var PropertyValueEvent =
  require('../../../../lib/mercury/property-value-event');

var store = require('../../../../lib/store');

var smartService = require('../../../../services/smart/service');
var getMethodData =
  require('../../../../services/namespace/interface-util').getMethodData;
var hashInterface =
  require('../../../../services/namespace/interface-util').hashInterface;

var log = require('../../../../lib/log')(
  'components:browse:item-details:method-form');

var h = mercury.h;


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

// While an unlimited # of items are predicted per input, it's a bad idea to
// show them all. Limit to 4 at a time, and rely on filtering to find the rest.
var METHOD_INPUT_MAX_ITEMS = 4;

/*
 * Create the base state and events necessary to render a method form.
 * Call the displayMethodForm event to fill this state with more data.
 */
function create() {
  var state = mercury.varhash({
    /*
     * Item name to target RPCs against.
     * @type {string}
     */
    itemName: mercury.value(''),

    /*
     * The item's interface.
     * @type {interface}
     */
    interface: mercury.value(null),

    /*
     * Method name for this method form
     * @type {string}
     */
    methodName: mercury.value(''),

    /*
     * Argument values that can be used to invoke the methodName RPC.
     * @type {Array<string>}
     */
    args: mercury.array([]),

    /*
     * Set of starred invocations saved by the user. There is no size limit.
     * An array is used to preserve order.
     * Each value in this array is a JSON-encoded array of argument values.
     * This only contains keys of starred items; unstarred ones are removed.
     * @type {Array<string>}
     */
    starred: mercury.array([]),

    /*
     * Limited list of invocations recommended to the user.
     * Each invocation is a JSON-encoded array of argument values.
     * Order affects rendering priority; some may never be rendered.
     * @type {Array<string>}
     */
    recommended: mercury.array([]),

    /*
     * The autocomplete suggestions for each of this method's inputs.
     * @type {Array<string>}
     */
    inputSuggestions: mercury.array([]),

    /*
     * Whether the method form is in its expanded state or not.
     * @type {boolean}
     */
    expanded: mercury.value(false)
  });

  var events = mercury.input([
    'displayMethodForm',     // the main event used to prepare the form data
    'methodStart',           // notify parent element of RPC start
    'methodEnd',             // notify parent element of RPC end result
    'runAction',             // run the RPC with given arguments
    'expandAction',          // show/hide method arguments
    'starAction',            // star/unstar a method invocation
    'removeRecommendation',  // remove and reload recommended invocations
    'removeInputSuggestion', // remove and reload input suggestions
    'toast'
  ]);
  wireUpEvents(state, events);

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

/*
 * Event handler that sets and prepares data into this form component.
 * data needs to include "itemName", "interface", and "methodName".
 */
function displayMethodForm(state, events, data) {
  // Set the given data into the state and prepare the method form.
  state.itemName.set(data.itemName);
  state.interface.set(data.interface);
  state.methodName.set(data.methodName);
  initializeInputArguments(state);

  // Prepare the remaining state asynchronously.
  refreshInputSuggestions(state).catch(function(err) {
    log.error('Could not get input suggestions for', data.methodName, err);
  });
  loadStarredInvocations(state).catch(function(err) {
    events.toast({
      text: 'Could not load stars for ' + data.methodName,
      type: 'error'
    });
    log.error('Could not load stars for', data.methodName, err);
  });
  refreshRecommendations(state).catch(function(err) {
    log.error('Could not get recommended invocations for',
      data.methodName, err);
  });
}

/*
 * Clear the mercury values related to the input arguments.
 */
function initializeInputArguments(state) {
  var param = getMethodData(state.interface(), state.methodName());
  var startingArgs = _.range(param.inArgs.length).map(function() {
    return ''; // Initialize array with empty string values using lodash.
  });
  setMercuryArray(state.args, startingArgs);
}

/*
 * Returns a promise that refreshes the suggestions to the input arguments.
 */
function refreshInputSuggestions(state) {
  var param = getMethodData(state.interface(), state.methodName());
  var input = {
    interface: state.interface(),
    methodName: state.methodName(),
  };
  return Promise.all(
    // For each argname, predict which inputs should be suggested.
    param.inArgs.map(function(inArg, i) {
      return smartService.predict(
        'learner-method-input',
        _.assign({argName: inArg.name}, input)
      ).then(function(inputSuggestion) {
        state.inputSuggestions.put(i, inputSuggestion);
      });
    })
  );
}

/*
 * Returns a promise that loads starred invocations into the state.
 */
function loadStarredInvocations(state) {
  return store.getValue(constructStarredInvocationKey(state)).then(
    function(result) {
      var invocations = result || [];
      state.put('starred', mercury.array(invocations));
    }
  ).catch(function(err) {
    log.error('Unable to load starred invocations from store', err);
    return Promise.reject(err);
  });
}

/*
 * Returns a promise that update the store with the invocations from the state.
 */
function saveStarredInvocations(state) {
  return store.setValue(
    constructStarredInvocationKey(state),
    state.starred()
  ).catch(function(err) {
    log.error('Unable to save starred invocations', err);
    return Promise.reject(err);
  });
}

/*
 * Given an observed state, produce the storage key.
 * The keys are of the form STARS|item|interface|method.
 * The corresponding value is an array of invocations.
 */
var starsPrefix = 'STARS';
function constructStarredInvocationKey(state) {
  var parts = [
    starsPrefix,
    state.itemName(),
    hashInterface(state.interface()),
    state.methodName()
  ];
  return parts.join('|');
}

/*
 * Returns a promise that refreshes the recommended values in the state.
 */
function refreshRecommendations(state) {
  var input = {
    interface: state.interface(),
    methodName: state.methodName(),
  };
  return smartService.predict('learner-method-invocation', input).then(
    function(recommendations) {
      setMercuryArray(state.recommended, recommendations);
    }
  );
}

/*
 * Wire up the events for the method form mercury component.
 * Note: Some events are left for the parent component to hook up.
 */
function wireUpEvents(state, events) {
  events.displayMethodForm(displayMethodForm.bind(null, state, events));

  // The run action triggers a start event, RPC call, and end event.
  events.runAction(function(data) {
    // This random value allows us to uniquely identify this RPC.
    var randomID = uuid.v4();
    events.methodStart({
      runID: randomID
    });

    // Toast that the RPC is being run.
    events.toast({
      text: 'Running ' + getMethodSignature(state(), data.args)
    });

    // Make the RPC, tracking when the method is in-progress or complete.
    makeRPC(data).then(function success(result) {
      events.methodEnd({
        runID: randomID,
        args: data.args,
        result: result
      });
    }, function failure(error) {
      events.methodEnd({
        runID: randomID,
        error: error
      });
    }).catch(function(err) {
      log.error('Error handling makeRPC', err);
    });
  });

  events.expandAction(function() {
    state.expanded.set(!state.expanded());
  });
  events.starAction(function(data) {
    // Load the user's stars (in case there were other changes).
    loadStarredInvocations(state).then(function() {
      // If there is no argsStr given, compute it now.
      var argsStr = data.argsStr || JSON.stringify(state.args());

      // Depending on the star boolean, add/remove a star for the given args.
      arraySet.set(state.starred, argsStr, data.star);

      // Save the user's star decision.
      return saveStarredInvocations(state);
    }).catch(function(err) {
      events.toast({
        text: 'Error while starring',
        type: 'error'
      });
      log.error('Error while starring invocation', err);
    });
  });

  // This event removes the specified recommendation.
  // Afterwards, the recommendations are refreshed.
  events.removeRecommendation(function(args) {
    var input = {
      interface: state.interface(),
      methodName: state.methodName(),
      value: JSON.stringify(args),
      reset: true
    };

    smartService.update('learner-method-invocation', input).then(function() {
      log.debug('Removing method invocation', input);
      return refreshRecommendations(state);
    }).then(function() {
      return events.toast({
        text: 'Removed suggestion: ' + getMethodSignature(state(), args),
        type: 'info'
      });
    }).catch(function(err) {
      var errText = 'Failed to remove suggestion';
      log.error(errText, err);
      events.toast({
        text: errText,
        type: 'error'
      });
    });
  });

  // This event removes the specified input suggestion for an argument.
  // Afterwards, all input suggestions are refreshed.
  events.removeInputSuggestion(function(data) {
    var input = {
      interface: state.interface(),
      methodName: state.methodName(),
      argName: data.argName,
      value: data.arg,
      reset: true
    };

    smartService.update('learner-method-input', input).then(function() {
      log.debug('Removing method input', input);
      return refreshInputSuggestions(state);
    }).catch(function(err) {
      var errText = 'Failed to remove suggestion';
      log.error(errText, err);
      events.toast({
        text: errText,
        type: 'error'
      });
    });
  });
}

/*
 * The main rendering function for the method form.
 * Shows the method signature and a run button.
 * If arguments are necessary, then they can be shown when the form is expanded.
 */
function render(state, events) {
  // Display the method name/sig header with expand/collapse/run button.
  var methodNameHeader = renderMethodHeader(state, events);

  // Return immediately if we don't need arguments or haven't expanded.
  if (state.args.length === 0 || !state.expanded) {
    return makeMethodTooltip(state, h('div.method-input', methodNameHeader));
  }

  // Render the stars first, and if there's extra room, the recommendations.
  // TODO(alexfandrianto): Show 1 of the pinned items even when not expanded?
  var recs = renderStarsAndRecommendations(state, events);

  // Form for filling up the arguments
  var argForm = []; // contains form elements
  for (var i = 0; i < state.args.length; i++) {
    argForm.push(renderMethodInput(state, events, i));
  }

  // Setup the STAR and RUN buttons.
  var starButton = renderStarUserInputButton(state, events);
  var runButton = renderRPCRunButton(state, events);

  var footer = h('div.method-input-expanded', [argForm, runButton, starButton]);
  return makeMethodTooltip(state,
    h('div.method-input', [methodNameHeader, recs, footer]));
}

/*
 * Wrap the method form with a tooltip.
 */
function makeMethodTooltip(state, child) {
  // The tooltip contains the documentation for the method name.
  var methodSig = getMethodData(state.interface, state.methodName);
  var tooltip = methodSig.doc || '<no description>';

  // If the method takes input, add documentation about the input arguments.
  if (methodSig.inArgs.length > 0) {
    tooltip += '\n\nParameters';
    methodSig.inArgs.forEach(function(inArg) {
      tooltip += '\n';
      tooltip += '- ' + inArg.name + ': ' + inArg.type.toString();
      if (inArg.doc) {
        tooltip += '  ' + inArg.doc;
      }
    });
  }

  // If the method returns output, add documentation about the output arguments.
  if (methodSig.outArgs.length > 0) {
    tooltip += '\n\nOutput';
    methodSig.outArgs.forEach(function(outArg) {
      tooltip += '\n';
      tooltip += '- ' + outArg.name + ': ' + outArg.type.toString();
      if (outArg.doc) {
        tooltip += '  ' + outArg.doc;
      }
    });
  }

  // If the method has tags, show the tag types and values.
  if (methodSig.tags.length > 0) {
    tooltip += '\n\nTags';
    methodSig.tags.forEach(function(tag) {
      tooltip += '\n';
      tooltip += '- ' + tag.val + ': ' + tag._type.name;
    });
  }

  return h('core-tooltip.tooltip.method-tooltip', {
    'label': tooltip,
    'position': 'top'
  }, child);
}

/*
 * Draw the method header: A method signature and either a run or expand button.
 */
function renderMethodHeader(state, events) {
  if (state.args.length === 0) {
    return renderInvocation(state, events);
  }
  var labelText = getMethodSignature(state);
  var label = makeMethodLabel(labelText);

  var expand = h('a.drill', {
    'href': 'javascript:;',
    'title': state.expanded ? 'Hide form' : 'Show form',
    'ev-click': mercury.event(events.expandAction)
  }, h('core-icon.action-icon', {
    attributes: {
      'icon': state.expanded ? 'expand-more' : 'chevron-right'
    }
  }));

  return h('div.item.card', [label, expand]);
}

/*
 * Extracts a pretty-printed version of the method signature.
 * If the method has no input args, print the name
 * If the method does have input args, also show parentheses
 * @args is an optional list whose elements are also printed out.
 */
function getMethodSignature(state, args) {
  var methodName = state.methodName;
  var param = getMethodData(state.interface, methodName);
  var text = methodName;
  var hasArgs = (param.inArgs.length > 0);
  if (hasArgs) {
    text += '(';
  }
  if (args !== undefined) {
    for (var i = 0; i < param.inArgs.length; i++) {
      if (i > 0) {
        text += ', ';
      }
      text += args[i];
    }
  } else if (hasArgs) {
    text += '...';
  }
  if (hasArgs) {
    text += ')';
  }
  if (param.inStream || param.outStream) {
    text += ' - streaming';
  }
  return text;
}


var SOFTCAP_INVOCATIONS = 3;
/*
 * Renders the starred invocations followed by the recommended ones. Stars are
 * shown with no limit. Recommendations are only shown if there is extra room.
 */
function renderStarsAndRecommendations(state, events) {
  var s = state.starred.map(
    function addStarred(invocation) {
      return renderInvocation(state, events, invocation);
    }
  );

  // Add the remaining recommenations, as long as they are not duplicates and
  // don't exceed the soft cap on the # of invocations shown.
  var remainingRecommendations = Math.min(
    SOFTCAP_INVOCATIONS - s.length,
    state.recommended.length
  );
  var count = 0;
  state.recommended.forEach(function(rec) {
    if (count < remainingRecommendations && state.starred.indexOf(rec) === -1) {
      s.push(renderInvocation(state, events, rec, true));
      count++;
    }
  });

  return s;
}

/*
 * Render the invocation, showing the method signature and a run button.
 * argsStr is optional and is used for starred and recommended invocations.
 * When given, then the card is smaller and has a star icon.
 */
function renderInvocation(state, events, argsStr, recommended) {
  var noArgs = argsStr === undefined;
  var args = noArgs ? [] : JSON.parse(argsStr);
  var labelText = getMethodSignature(state, args);
  var label = makeMethodLabel(labelText);

  var runButton = h('a.drill', {
    'href': 'javascript:;',
    'title': 'Run ' + state.methodName,
    'ev-click': getRunEvent(state, events, args)
  }, renderPlayIcon());

  if (noArgs) {
    return h('div.item.card', [label, runButton]);
  }

  var starred = state.starred.indexOf(argsStr) !== -1;
  var starButton = h('a.drill.star', {
    'href': 'javascript:;',
    'title': starred ? 'Forget Method Call' : 'Save Method Call',
    'ev-click': mercury.event(events.starAction, {
      argsStr: argsStr,
      star: !starred
    })
  }, renderStarIcon(starred));

  var negFeedback;
  if (recommended) {
    negFeedback = h('div.action-bar', h('paper-fab', {
      attributes: {
        'aria-label': 'Remove suggestion',
        'title': 'Remove suggestion',
        'icon': 'clear',
        'mini': true
      },
      'ev-click': events.removeRecommendation.bind(null, args)
    }));
  }

  return h('div.item.card.invocation',
    [starButton, label, runButton, negFeedback]
  );
}

/*
 * Render a method label using labelText.
 */
function makeMethodLabel(labelText) {
  return h('div.label', labelText);
}

/*
 * Draws a single method argument input using the paper-autocomplete element.
 * Includes a placeholder and suggestions from the internal state.
 */
function renderMethodInput(state, events, index) {
  var methodName = state.methodName;
  var inArg = getMethodData(state.interface, state.methodName).inArgs[index];
  var argName = inArg.name;
  var argTypeStr = inArg.type.name || inArg.type.toString();
  var inputSuggestions = state.inputSuggestions[index];
  var args = state.args;

  // The children are the suggestions for this paper-autocomplete input.
  var children = inputSuggestions.map(function(suggestion) {
    return h('paper-item', {
      attributes: {
        // Attach as an attribute for later retrieval
        'input-suggestion': suggestion
      }
    }, suggestion);
  });

  // Event used to update state when the value is changed.
  var changeEvent = new PropertyValueEvent(function(data) {
    log.debug(methodName, argName, 'value changed.', data);
    args[index] = data;
  }, 'value');

  // TODO(alexfandrianto): It may be nice to link feedback between the
  // method-input and method-invocation learners.
  // Event used to remove an input suggestion.
  var removeEvent = function(e) {
    events.removeInputSuggestion({
      argName: argName,
      arg: e.target.getAttribute('input-suggestion')
    });
  };

  // TODO(alexfandrianto): Note that Mercury and Polymer create a bug together.
  // Polymer normally captures internal events and stops them from propagating.
  // Unfortunately, Mercury reads and replays events using capturing mode.
  // That means spurious 'change' and 'input' events may appear occasionally.
  var elem = h('paper-autocomplete.method-input-item.autocomplete', {
    'key': state.itemName, // Enforce element refresh when switching items
    attributes: {
      'label': argName + ' (' + argTypeStr + ')',
      'value': args[index],
      'spellcheck': 'false',
      'maxItems': METHOD_INPUT_MAX_ITEMS
    },
    'ev-change': changeEvent,
    'ev-delete-item': removeEvent
  }, children);

  return elem;
}

/*
 * Draws the STAR button with the star event, which saves the user's input.
 */
function renderStarUserInputButton(state, events) {
  var starButton = h(
    'paper-button.secondary',
    {
      'href': 'javascript:;',
      attributes: {
        'raised': 'true'
      },
      'ev-click': mercury.event(events.starAction, {
        star: true
      })
    },
    [
      renderStarIcon(false),
      h('span', 'Save')
    ]
  );
  return starButton;
}

/*
 * Draws the RUN button with the RPC run event with the user's input as args.
 */
function renderRPCRunButton(state, events) {
  var runButton = h(
    'paper-button',
    {
      'href': 'javascript:;',
      attributes: {
        'raised': 'true'
      },
      'ev-click': getRunEvent(state, events, state.args)
    },
    [
      renderPlayIcon(),
      h('span', 'Run')
    ]
  );
  return runButton;
}

/*
 * The generic run event for making RPCs. In general, the arguments are taken
 * from state.args, a starred invocation's arguments, or a recommendation's.
 */
function getRunEvent(state, events, args) {
  return mercury.event(events.runAction, {
    name: state.itemName,
    methodName: state.methodName,
    args: args
  });
}

/*
 * Render a star icon.
 */
function renderStarIcon(starred) {
  return h('core-icon.action-icon' + (starred ? '.starred' : ''), {
    attributes: {
      'icon': starred ? 'star' : 'star-outline',
      'alt': starred ? 'saved' : 'recommended'
    }
  });
}

/*
 * Render a play icon.
 */
function renderPlayIcon() {
  return h('core-icon..action-icon', {
    attributes: {
      'icon': 'av:play-circle-outline',
      'alt': 'run'
    }
  });
}
