"use strict";

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

var _util = require("@polkadot/util");

var _createClass = require("./createClass");

// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
function u8aHasValue(value) {
  return value.some(v => !!v);
} // With isPedantic, actually check that the encoding matches that supplied. This
// is much slower, but verifies that we have the correct types defined


function checkInstance(value, created) {
  // For option, we are not adding  the initial byte (this is via storage)
  const crHex = created.toHex(true);
  const inHex = (0, _util.u8aToHex)(value); // if the hex doesn't match and the value for both is non-empty, complain... bitterly

  if (inHex !== crHex && (u8aHasValue(value) || u8aHasValue(created.toU8a(true)))) {
    console.warn("".concat(created.toRawType(), ":: Input doesn't match output, received ").concat(inHex, ", created ").concat(crHex));
  }
} // Initializes a type with a value. This also checks for fallbacks and in the cases
// where isPedantic is specified (storage decoding), also check the format/structure


function initType(Type) {
  let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  let isPedantic = arguments.length > 2 ? arguments[2] : undefined;
  const created = new Type(...params);
  const [value] = params;

  if (isPedantic && (0, _util.isU8a)(value)) {
    checkInstance(value, created);
  }

  return created;
} // An unsafe version of the `createType` below. It's unsafe because the `type`
// argument here can be any string, which, if not parseable, will yield a
// runtime error.


function createTypeUnsafe(type) {
  let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  let isPedantic = arguments.length > 2 ? arguments[2] : undefined;

  try {
    return initType((0, _createClass.createClass)(type), params, isPedantic);
  } catch (error) {
    throw new Error("createType(".concat(type, "):: ").concat(error.message));
  }
}
/**
 * Create an instance of a `type` with a given `params`.
 * @param type - A recognizable string representing the type to create an
 * instance from
 * @param params - The value to instantiate the type with
 */


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

  // error TS2589: Type instantiation is excessively deep and possibly infinite.
  // The above happens with as Constructor<InterfaceRegistry[K]>;
  return createTypeUnsafe(type, params);
}