"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.MapOfType = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _typeDetect = _interopRequireDefault(require("type-detect"));
var _errors = require("../errors");
var _internals = require("../internals");
var _type = require("./type");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

class MapOfType extends _type.Type {
  constructor(keyType, valueType, options = {}) {
    const defaultValue = options.defaultValue;
    const schema = _internals.internals.map().entries(keyType.getSchema(), valueType.getSchema());
    super(schema, {
      ...options,
      // Joi clones default values with `Hoek.clone`, and there is bug in cloning
      // of Map/Set/Promise/Error: https://github.com/hapijs/hoek/issues/228.
      // The only way to avoid cloning and hence the bug is to use function for
      // default value instead.
      defaultValue: defaultValue instanceof Map ? () => defaultValue : defaultValue
    });
    (0, _defineProperty2.default)(this, "keyType", void 0);
    (0, _defineProperty2.default)(this, "valueType", void 0);
    (0, _defineProperty2.default)(this, "mapOptions", void 0);
    this.keyType = keyType;
    this.valueType = valueType;
    this.mapOptions = options;
  }
  extendsDeep(options) {
    return new MapOfType(this.keyType.extendsDeep(options), this.valueType.extendsDeep(options), this.mapOptions);
  }
  handleError(type, {
    entryKey,
    reason,
    value
  }, path) {
    switch (type) {
      case 'any.required':
      case 'map.base':
        return `expected value of type [Map] or [object] but got [${(0, _typeDetect.default)(value)}]`;
      case 'map.parse':
        return `could not parse map value from json input`;
      case 'map.key':
      case 'map.value':
        const childPathWithIndex = path.slice();
        childPathWithIndex.splice(path.length, 0,
        // If `key` validation failed, let's stress that to make error more obvious.
        type === 'map.key' ? `key("${entryKey}")` : entryKey.toString(),
        // Error could have happened deep inside value/key schema and error message should
        // include full path.
        ...(reason instanceof _errors.SchemaTypeError ? reason.path : []));
        return reason instanceof _errors.SchemaTypesError ? new _errors.SchemaTypesError(reason, childPathWithIndex, reason.errors) : new _errors.SchemaTypeError(reason, childPathWithIndex);
    }
  }
}
exports.MapOfType = MapOfType;