/*************************************
 * IBM Watson Alchemy Languge API v1.0
 * By: Russ Savage (@russellsavage)
 * Usage:
 *  var watson = new AlchemyLanguageAPI({
 *    "url": "https://gateway-a.watsonplatform.net/calls",
 *    "apikey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 *  });
 * // Example usage:
 * var resp = watson.URLGetRankedKeywords({ 
 *   url : 'http://searchengineland.com/send-adwords-alerts-directly-slack-adwords-script-library-243870' 
 * });
 * 
 * Full documentation on parameters can be found here:
 * http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/alchemy-language/api/v1/
 ***********************************/
function AlchemyLanguageAPI(config) {
  this.api_key = config.apikey;
  this.base_url = config.url;
  
  // This is a generic function to pull data from an endpoint
  // and send it back as a json object.
  this.callService = function(endpoint, conf) {
    conf.apikey = this.api_key;
    conf.outputMode = 'json';
    
    var params = {
      method : "POST",
      payload : _buildQueryString(conf),
      muteHttpExceptions : true
    };
    var resp = UrlFetchApp.fetch(this.base_url+endpoint, params);
    var jsonResp = JSON.parse(resp.getContentText());
    if(jsonResp.status == "OK") {
      return JSON.parse(resp.getContentText());
    } else {
      throw jsonResp.status + " : " + jsonResp.statusInfo;
    }
  };
  
  // This function is used to dynamically generate the individual endpoints of each endpoint.
  this.generateFunctions = function() {
    var endpoints = _getEndpoints();
    for(var i in endpoints) {
      var endpoint = endpoints[i];
      this[endpoint] = new Function('params', "return this.callService('/url/"+endpoint+"', params);");
    }
  };
  
  // This is a list of endpoints from the docs used for dynamically generating our functions
  // http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/alchemy-language/api/v1/
  function _getEndpoints() {
    return ['URLGetCombinedData','URLGetAuthors','URLGetRankedConcepts',
            'URLExtractDates','URLGetEmotion','URLGetRankedNamedEntities',
            'URLGetFeedLinks','URLGetRankedKeywords','URLGetLanguage',
            'URLGetMicroformatData','URLGetPubDate','URLGetRelations',
            'URLGetTypedRelations','URLGetTextSentiment','URLGetTargetedSentiment',
            'URLGetRankedTaxonomy','URLGetText','URLGetRawText','URLGetTitle'];
  };
    
  // This is our helper method to build the query string from
  // the config object.
  function _buildQueryString(keyValueMap) {
    var query_string = [];
    if(keyValueMap) {
      Object.keys(keyValueMap).forEach(function(key) {
        query_string.push(key+'='+encodeURIComponent(keyValueMap[key]));
      });
    }
    return query_string.join('&');
  }
  
  this.generateFunctions();
}