"use strict";

exports.__esModule = true;
// istanbul ignore next

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } }

// istanbul ignore next

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

// istanbul ignore next

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var _pluginPass = require("./plugin-pass");

var _pluginPass2 = _interopRequireDefault(_pluginPass);

var _messages = require("../messages");

var messages = _interopRequireWildcard(_messages);

var _traversal = require("../traversal");

var _traversal2 = _interopRequireDefault(_traversal);

var _lodashObjectAssign = require("lodash/object/assign");

var _lodashObjectAssign2 = _interopRequireDefault(_lodashObjectAssign);

var _lodashLangClone = require("lodash/lang/clone");

var _lodashLangClone2 = _interopRequireDefault(_lodashLangClone);

var _file = require("./file");

var _file2 = _interopRequireDefault(_file);

var _types = require("../types");

var t = _interopRequireWildcard(_types);

var VALID_PLUGIN_PROPERTIES = ["visitor", "metadata", "manipulateOptions", "post", "pre"];

var VALID_METADATA_PROPERTES = ["dependencies", "optional", "stage", "group", "experimental", "secondPass"];

/**
 * [Please add a description.]
 */

var Plugin = (function () {
  function Plugin(key, plugin) {
    _classCallCheck(this, Plugin);

    Plugin.validate(key, plugin);

    plugin = _lodashObjectAssign2["default"]({}, plugin);

    var take = function take(key) {
      var val = plugin[key];
      delete plugin[key];
      return val;
    };

    this.manipulateOptions = take("manipulateOptions");
    this.metadata = take("metadata") || {};
    this.dependencies = this.metadata.dependencies || [];
    this.post = take("post");
    this.pre = take("pre");

    //

    if (this.metadata.stage != null) {
      this.metadata.optional = true;
    }

    //

    this.visitor = this.normalize(_lodashLangClone2["default"](take("visitor")) || {});
    this.key = key;
  }

  /**
   * [Please add a description.]
   */

  Plugin.validate = function validate(name, plugin) {
    for (var key in plugin) {
      if (key[0] === "_") continue;
      if (VALID_PLUGIN_PROPERTIES.indexOf(key) >= 0) continue;

      var msgType = "pluginInvalidProperty";
      if (t.TYPES.indexOf(key) >= 0) msgType = "pluginInvalidPropertyVisitor";
      throw new Error(messages.get(msgType, name, key));
    }

    for (var key in plugin.metadata) {
      if (VALID_METADATA_PROPERTES.indexOf(key) >= 0) continue;

      throw new Error(messages.get("pluginInvalidProperty", name, "metadata." + key));
    }
  };

  /**
   * [Please add a description.]
   */

  Plugin.prototype.normalize = function normalize(visitor) {
    _traversal2["default"].explode(visitor);
    return visitor;
  };

  /**
   * [Please add a description.]
   */

  Plugin.prototype.buildPass = function buildPass(file) {
    // validate Transformer instance
    if (!(file instanceof _file2["default"])) {
      throw new TypeError(messages.get("pluginNotFile", this.key));
    }

    return new _pluginPass2["default"](file, this);
  };

  return Plugin;
})();

exports["default"] = Plugin;
module.exports = exports["default"];