'use strict';

require('../../utils/types/array.cjs');
var utils_types_string = require('../../utils/types/string.cjs');
require('crypto');
require('bs58');
require('multiformats/bases/base58');
require('varint');
require('../../utils/encoding/ss-58.cjs');
var resolver_generic_const = require('./const.cjs');
require('../../utils/inheritance.cjs');
require('../../utils/types/object.cjs');
require('../../utils/types/iterable.cjs');
require('../../utils/types/set.cjs');
require('blake2b');
require('../../utils/types/bytes.cjs');
require('../../utils/interfaces.cjs');
require('../../utils/assert.cjs');
require('../../utils/error.cjs');

/**
 * @class
 * @abstract
 * @template T
 */
class Resolver {
  /**
   * Matching prefix - either a string, array of strings or wildcard pattern.
   * @type {Array<string> | string | symbol}
   * @prop prefix
   */

  /**
   * Matching method - either a string, array of strings or wildcard pattern.
   * @type {Array<string> | string | symbol}
   * @prop method
   *

  /**
   * Returns `true` if an entity with the provided identifier can be resolved using this resolver.
   * @param {string} id - fully qualified identifier.
   * @returns {boolean}
   */
  supports(id) {
    utils_types_string.ensureString(id);
    const methods = [].concat(this.method);
    const prefixes = [].concat(this.prefix);

    return (
      (methods.includes(resolver_generic_const.WILDCARD)
        || methods.includes(this.extractMethod(id)))
      && (prefixes.includes(resolver_generic_const.WILDCARD) || prefixes.includes(this.extractPrefix(id)))
    );
  }

  /**
   * Resolves an entity with the provided identifier.
   * @abstract
   * @param {string} id - fully qualified identifier.
   * @returns {Promise<T>}
   */
  async resolve(id) {
    throw new Error(
      `Unimplemented \`resolve\` for \`${this.constructor.name}\`, can't resolve \`${id}\``,
    );
  }

  /**
   * Extracts a prefix from the provided identifier.
   *
   * @param {string} id
   * @returns {string}
   */
  extractPrefix(id) {
    utils_types_string.ensureString(id);
    const end = id.indexOf(':');

    // eslint-disable-next-line no-bitwise
    return ~end ? id.slice(0, end) : '';
  }

  /**
   * Extracts a method from the provided identifier.
   *
   * @param {string} id
   * @returns {string}
   */
  extractMethod(id) {
    utils_types_string.ensureString(id);
    const start = id.indexOf(':');
    const end = id.indexOf(':', start + 1);

    // eslint-disable-next-line no-bitwise
    return ~start && ~end ? id.slice(start + 1, end) : '';
  }
}

module.exports = Resolver;
//# sourceMappingURL=resolver.cjs.map
