// Generated by CoffeeScript 1.6.2
var PluginLoader, pathUtil, safefs, semver, util,
  __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

pathUtil = require('path');

semver = require('semver');

safefs = require('safefs');

util = require('util');

PluginLoader = (function() {
  PluginLoader.prototype.docpad = null;

  PluginLoader.prototype.BasePlugin = null;

  PluginLoader.prototype.dirPath = null;

  PluginLoader.prototype.packagePath = null;

  PluginLoader.prototype.packageData = {};

  PluginLoader.prototype.pluginPath = null;

  PluginLoader.prototype.pluginClass = {};

  PluginLoader.prototype.pluginName = null;

  PluginLoader.prototype.pluginVersion = null;

  PluginLoader.prototype.nodeModulesPath = null;

  function PluginLoader(_arg) {
    this.docpad = _arg.docpad, this.dirPath = _arg.dirPath, this.BasePlugin = _arg.BasePlugin;
    docpad = this.docpad;
    this.pluginName = pathUtil.basename(this.dirPath).replace(/^docpad-plugin-/, '');
    this.pluginClass = {};
    this.packageData = {};
    this.nodeModulesPath = pathUtil.resolve(this.dirPath, 'node_modules');
  }

  PluginLoader.prototype.exists = function(next) {
    var failure, packagePath, success,
      _this = this;

    packagePath = this.packagePath || pathUtil.resolve(this.dirPath, "package.json");
    failure = function(err) {
      if (err == null) {
        err = null;
      }
      return next(err, false);
    };
    success = function() {
      return next(null, true);
    };
    safefs.exists(packagePath, function(exists) {
      if (!exists) {
        return failure();
      }
      _this.packagePath = packagePath;
      return safefs.readFile(packagePath, function(err, data) {
        var pluginPath, pluginVersion;

        if (err) {
          return failure(err);
        }
        try {
          _this.packageData = JSON.parse(data.toString());
        } catch (_error) {
          err = _error;
          return failure(err);
        } finally {
          if (!_this.packageData) {
            return failure();
          }
        }
        pluginVersion = _this.packageData.version;
        pluginPath = _this.packageData.main && pathUtil.join(_this.dirPath, _this.packageData.main);
        if (!pluginVersion) {
          return failure();
        }
        if (!pluginPath) {
          return failure();
        }
        _this.pluginPath = pluginVersion;
        _this.pluginPath = pluginPath;
        return success();
      });
    });
    return this;
  };

  PluginLoader.prototype.unsupported = function(next) {
    var docpad, engines, keywords, platforms, unsupported, _ref;

    docpad = this.docpad;
    unsupported = false;
    keywords = this.packageData.keywords || [];
    if (__indexOf.call(keywords, 'docpad-plugin') < 0) {
      unsupported = 'type';
    }
    if (this.packageData.platforms) {
      platforms = this.packageData.platforms || [];
      if (_ref = process.platform, __indexOf.call(platforms, _ref) < 0) {
        unsupported = 'platform';
      }
    }
    if (this.packageData.engines) {
      engines = this.packageData.engines || {};
      if (engines.node != null) {
        if (!semver.satisfies(process.version, engines.node)) {
          unsupported = 'engine';
        }
      }
      if (engines.docpad != null) {
        if (!semver.satisfies(docpad.version, engines.docpad)) {
          unsupported = 'version';
        }
      }
    }
    next(null, unsupported);
    return this;
  };

  PluginLoader.prototype.install = function(next) {
    var docpad;

    docpad = this.docpad;
    if (this.packagePath) {
      docpad.initNodeModules({
        path: this.dirPath,
        next: function(err, results) {
          return next(err);
        }
      });
    } else {
      next();
    }
    return this;
  };

  PluginLoader.prototype.load = function(next) {
    var docpad, err, locale, pluginPrototypeName, validPluginName, _base, _ref;

    docpad = this.docpad;
    locale = docpad.getLocale();
    try {
      this.pluginClass = require(this.pluginPath)(this.BasePlugin);
      if ((_ref = (_base = this.pluginClass.prototype).version) == null) {
        _base.version = this.pluginVersion;
      }
      pluginPrototypeName = this.pluginClass.prototype.name;
      if (/^[a-z0-9]+$/.test(this.pluginName) === false) {
        validPluginName = this.pluginName.replace(/[^a-z0-9]/, '');
        docpad.log('warn', util.format(locale.pluginNamingConventionInvalid, this.pluginName, validPluginName));
      }
      if (pluginPrototypeName === null) {
        this.pluginClass.prototype.name = this.pluginName;
        docpad.log('warn', util.format(locale.pluginPrototypeNameUndefined, this.pluginName));
      } else if (pluginPrototypeName !== this.pluginName) {
        docpad.log('warn', util.format(locale.pluginPrototypeNameDifferent, this.pluginName, pluginPrototypeName));
      }
    } catch (_error) {
      err = _error;
      return next(err, null);
    }
    next(null, this.pluginClass);
    return this;
  };

  PluginLoader.prototype.create = function(config, next) {
    var docpad, err, pluginInstance;

    try {
      docpad = this.docpad;
      pluginInstance = new this.pluginClass({
        docpad: docpad,
        config: config
      });
    } catch (_error) {
      err = _error;
      return next(err, null);
    }
    return next(null, pluginInstance);
    return this;
  };

  return PluginLoader;

})();

module.exports = PluginLoader;