define('ember-cp-validations/validators/base', ['exports', 'ember-cp-validations/validators/messages', 'ember-cp-validations/-private/options', 'ember-cp-validations/utils/lookup-validator', 'ember-cp-validations/utils/utils'], function (exports, _messages, _options, _lookupValidator, _utils) {
  'use strict';

  Object.defineProperty(exports, "__esModule", {
    value: true
  });

  function _toConsumableArray(arr) {
    if (Array.isArray(arr)) {
      for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];

      return arr2;
    } else {
      return Array.from(arr);
    }
  }

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

  var TestResult = function TestResult(result) {
    _classCallCheck(this, TestResult);

    this.isValid = result === true;
    this.message = typeof result === 'string' ? result : null;
  };

  /**
   * @class Base
   * @module Validators
   */
  var Base = Ember.Object.extend({
    /**
     * Options passed in to the validator when defined in the model
     * @property options
     * @type {Object}
     */
    options: null,

    /**
     * Default validation options for this specific attribute
     * @property defaultOptions
     * @type {Object}
     */
    defaultOptions: null,

    /**
     * Global validation options for this model
     * @property globalOptions
     * @type {Object}
     */
    globalOptions: null,

    /**
     * Model instance
     * @property model
     * @type {Model}
     */
    model: null,

    /**
     * Attributed name of the model this validator is attached to
     * @property attribute
     * @type {String}
     */
    attribute: null,

    /**
     * Error message object. Populated by validators/messages
     * @property errorMessages
     * @type {Object}
     */
    errorMessages: null,

    /**
     * @property isWarning
     * @type {Boolean}
     */
    isWarning: Ember.computed.bool('options.isWarning').readOnly(),

    /**
     * Validator type
     * @property _type
     * @private
     * @type {String}
     */
    _type: null,

    /**
     * Validators cache used by `test` api
     * @property _testValidatorCache
     * @private
     * @type {Object}
     */
    _testValidatorCache: Ember.computed(function () {
      return {};
    }).readOnly(),

    init: function init() {
      this._super.apply(this, arguments);
      var globalOptions = Ember.get(this, 'globalOptions');
      var defaultOptions = Ember.get(this, 'defaultOptions');
      var options = Ember.get(this, 'options');
      var owner = Ember.getOwner(this);
      var errorMessages = void 0;

      if (!Ember.isNone(owner)) {
        // Since default error messages are stored in app/validators/messages, we have to look it up via the owner
        errorMessages = owner.factoryFor('validator:messages');
      }

      // If for some reason, we can't find the messages object (i.e. unit tests), use default
      errorMessages = errorMessages || _messages.default;

      Ember.set(this, 'options', this.buildOptions(options, defaultOptions, globalOptions));
      Ember.set(this, 'errorMessages', errorMessages.create());
    },
    buildOptions: function buildOptions() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var defaultOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var globalOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

      var builtOptions = (0, _utils.mergeOptions)(options, defaultOptions, globalOptions);

      // Overwrite the validator's value method if it exists in the options and remove it since
      // there is no need for it to be passed around
      this.value = builtOptions.value || this.value;
      delete builtOptions.value;

      return new _options.default({
        model: Ember.get(this, 'model'),
        attribute: Ember.get(this, 'attribute'),
        options: builtOptions
      });
    },
    value: function value(model, attribute) {
      return Ember.get(model, attribute);
    },
    getValue: function getValue() {
      var value = this.value(Ember.get(this, 'model'), Ember.get(this, 'attribute'));
      return (0, _utils.getValidatableValue)(value);
    },
    validate: function validate() {
      return true;
    },
    createErrorMessage: function createErrorMessage(type, value) {
      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

      var messages = this.get('errorMessages');
      var message = (0, _utils.unwrapString)(Ember.get(options, 'message'));

      Ember.set(options, 'description', messages.getDescriptionFor(Ember.get(this, 'attribute'), options));

      if (message) {
        if (typeof message === 'string') {
          message = messages.formatMessage(message, options);
        } else if (typeof message === 'function') {
          message = message.apply(this, arguments);
          message = Ember.isNone(message) ? messages.getMessageFor(type, options) : messages.formatMessage(message, options);
        }
      } else {
        message = messages.getMessageFor(type, options);
      }

      return message.trim();
    },
    test: function test(type) {
      var _cache$type;

      var cache = this.get('_testValidatorCache');
      var unsupportedTypes = ['alias', 'belongs-to', 'dependent', 'has-many'];

      if (unsupportedTypes.includes(type)) {
        throw new Error('[ember-cp-validations] The `test` API does not support validators of type: ' + type + '.');
      }

      cache[type] = cache[type] || (0, _lookupValidator.default)(Ember.getOwner(this), type).create();

      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }

      var result = (_cache$type = cache[type]).validate.apply(_cache$type, _toConsumableArray(args));

      if ((0, _utils.isPromise)(result)) {
        return result.then(function (r) {
          return new TestResult(r);
        }, function (r) {
          return new TestResult(r);
        });
      }

      return new TestResult(result);
    }
  });

  Base.reopenClass({
    getDependentsFor: function getDependentsFor() {
      return [];
    }
  });

  exports.default = Base;
});