/*
 *   Copyright 2014 Guy Bedford (http://guybedford.com)
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
var fs = require('graceful-fs');
var path = require('path');
var config = require('./config');
var globalConfig = require('./global-config');
var ui = require('./ui');
var extend = require('./common').extend;

process.on('exit', function() {
  // dispose all loaded endpoints
  // allows for saving cache state using sync fs
  for (var e in endpointClasses) {
    if (endpointClasses[e].dispose)
      endpointClasses[e].dispose();
  }
});

var ep = exports;

/*
  Endpoint API
  See https://github.com/jspm/jspm-cli/wiki/Endpoint-API for the spec
*/
var endpointClasses = {
  local: {
    lookup: function() {
      throw 'Local endpoint can only be used for linking. Try %jspm install -l local:...%';
    }
  }
};

exports.load = function(endpoint) {
  // add local as an endpoint if not existing, this way only created when used
  if (endpoint == 'local' && !globalConfig.config.endpoints.local) {
    globalConfig.config.endpoints.local = {};
    globalConfig.save();
  }
  if (endpointClasses[endpoint])
    return endpointClasses[endpoint];

  try {
    // ensure the tmpDir exists
    var tmpDir = path.resolve(config.HOME, '.jspm', endpoint + '-cache');
    if (!fs.existsSync(tmpDir))
      fs.mkdirSync(tmpDir);

    var options = {
      timeout: 120, 
      tmpDir: tmpDir,
      apiVersion: '1.0'
    };
    extend(options, globalConfig.config.endpoints[endpoint] || {});

    options.name = endpoint;

    if (!options.handler)
      throw 'Endpoint not found.';

    var endpointClass = require(options.handler);
    var endpointPackageJSON = require(options.handler + '/package.json');
    var versionString = endpointPackageJSON.name + '@' + endpointPackageJSON.version.split('.').splice(0, 2).join('.');
    options.versionString = versionString;

    var endpointInstance = endpointClasses[endpoint] = new endpointClass(options, ui);

    // allow options to have been mutated by constructor
    delete options.timeout;
    delete options.tmpDir;
    delete options.apiVersion;
    delete options.versionString;
    delete options.name;
    globalConfig.config.endpoints[endpoint] = options;
    globalConfig.save();

    endpointInstance.versionString = endpointInstance.versionString || versionString;

    return endpointInstance;
  }
  catch(e) {
    ui.log('err', e.stack || e);
    throw 'Unable to load endpoint %' + endpoint + '%';
  }
}

exports.configure = function(endpoint) {
  var endpointConfig = globalConfig.config.endpoints[endpoint] || {};

  if (!endpointConfig.handler)
    throw 'Endpoint %' + endpoint + '% not found.';

  var handler = endpointConfig.handler;
  delete endpointConfig.handler;

  try {
    var endpointClass = require(handler);
  }
  catch(e) {
    throw 'Endpoint handler`' + handler + '` not installed.';
  }

  endpointConfig.name = endpoint;
  return Promise.resolve(endpointClass.configure && endpointClass.configure(endpointConfig, ui) || endpointConfig)
  .then(function(_config) {
    delete _config.name;
    _config.handler = handler;
    globalConfig.config.endpoints[endpoint] = _config;
  })
  .then(function() {
    globalConfig.save();
  });
}

// jspm endpoint create mycompany jspm-github
// creates a custom endpoint based on the given handler
exports.create = function(name, handler, override) {

  // handle override prompts etc
  if (!override && globalConfig.config.endpoints[name]) {
    if (globalConfig.config.endpoints[name].handler == handler)
      return ui.confirm('Endpoint %' + name + '% already exists. Do you want to reconfigure it now?')
      .then(function(configure) {
        if (configure)
          return Promise.resolve(exports.configure(name))
          .then(function() {
            ui.log('ok', 'Endpoint %' + name + '% configured successfully.');
            return false;
          });
        else
          return false;
      });
    else
      return ui.confirm('Endpoint %' + name + '% already exists, but based on `' + handler + '`. Are you sure you want to override it?')
      .then(function(override) {
        if (override)
          return Promise.resolve(exports.create(name, handler, true));
        return false;
      });
  }

  var endpointConfig = globalConfig.config.endpoints[name] = globalConfig.config.endpoints[name] || {};
  endpointConfig.handler = handler;

  // load the endpoint and configure it
  return exports.configure(name);
}
@@ -4560,24 +4560,60 @@
 sed on %60' + 
+globalConfig.config.endpoints%5Bname%5D.
 handler + '%60
@@ -5029,12 +5029,13 @@
 ure(name);%0A%7D
+%0A

Fix endpoint config override handler name