'use strict';

var jsonld = require('jsonld');
var jsonWebSignature = require('@transmute/json-web-signature');
var vc_documentLoader = require('./document-loader.cjs');
require('./crypto/Bls12381BBDT16KeyPairDock2024.cjs');
var vc_crypto_Bls12381BBDT16MACDock2024 = require('./crypto/Bls12381BBDT16MACDock2024.cjs');
require('./crypto/Bls12381BBDT16MACProofDock2024.cjs');
require('./crypto/Bls12381BBSKeyPairDock2023.cjs');
var vc_crypto_Bls12381BBSSignatureDock2022 = require('./crypto/Bls12381BBSSignatureDock2022.cjs');
var vc_crypto_Bls12381BBSSignatureDock2023 = require('./crypto/Bls12381BBSSignatureDock2023.cjs');
require('./crypto/Bls12381BBSSignatureProofDock2022.cjs');
require('./crypto/Bls12381BBSSignatureProofDock2023.cjs');
require('./crypto/Bls12381BDDT16KeyPairDock2024.cjs');
require('./crypto/Bls12381BDDT16MACDock2024.cjs');
require('./crypto/Bls12381BDDT16MACProofDock2024.cjs');
require('./crypto/Bls12381G2KeyPairDock2022.cjs');
require('./crypto/Bls12381PSKeyPairDock2023.cjs');
var vc_crypto_Bls12381PSSignatureDock2023 = require('./crypto/Bls12381PSSignatureDock2023.cjs');
require('./crypto/Bls12381PSSignatureProofDock2023.cjs');
var vc_crypto_EcdsaSecp256k1Signature2019 = require('./crypto/EcdsaSecp256k1Signature2019.cjs');
require('bs58');
require('@juanelas/base64');
require('crypto');
var vc_crypto_constants = require('./crypto/constants.cjs');
require('../keypairs/keypair-secp256k1.cjs');
require('multiformats/bases/base58');
var vc_crypto_Ed25519Signature2018 = require('./crypto/Ed25519Signature2018.cjs');
var vc_crypto_Ed25519Signature2020 = require('./crypto/Ed25519Signature2020.cjs');
require('@stablelib/ed25519');
require('../types/public-keys/public-key.cjs');
require('../types/public-keys/public-key-sr25519-value.cjs');
require('../types/public-keys/public-key-ed25519-value.cjs');
require('../types/public-keys/public-key-secp256k1-value.cjs');
require('../types/public-keys/public-key-x25519-value.cjs');
require('../types/signatures/signature-value.cjs');
require('../types/signatures/signature.cjs');
require('../utils/types/array.cjs');
require('varint');
require('../utils/encoding/ss-58.cjs');
require('../keypairs/dock-keypair.cjs');
var vc_crypto_JsonWebSignature2020 = require('./crypto/JsonWebSignature2020.cjs');
require('./crypto/common/CustomLinkedDataSignature.cjs');
var keypairs_didKeypair = require('../keypairs/did-keypair.cjs');
var types_did_document_verificationMethodRef = require('../types/did/document/verification-method-ref.cjs');
require('./contexts.cjs');
require('./contexts/vc-examples-v1.cjs');
require('./contexts/security_context.cjs');
require('./contexts/status-list-21.cjs');
require('./contexts/private-status-list-21.cjs');
require('../utils/json-fetch.cjs');
require('@docknetwork/crypto-wasm-ts');
require('./crypto/common/DockCryptoKeyPair.cjs');
require('../utils/types/bytes.cjs');
require('../utils/interfaces.cjs');
require('../utils/assert.cjs');
require('../utils/error.cjs');
require('../utils/types/string.cjs');
require('../utils/types/iterable.cjs');
require('../utils/types/object.cjs');
require('../utils/inheritance.cjs');
require('../utils/types/set.cjs');
require('@docknetwork/crypto-wasm-ts/lib/index.js');
require('./crypto/common/DockCryptoSignature.cjs');
require('jsonld-signatures');
require('json-stringify-deterministic');
require('semver/preload.js');
require('base64url');
require('../types/generic/typed-enum.cjs');
require('../types/generic/with-base.cjs');
require('../types/generic/with-catch-null.cjs');
require('../types/generic/with-eq.cjs');
require('../types/generic/any-of.cjs');
require('../types/generic/with-from.cjs');
require('blake2b');
require('../types/generic/with-from-json-bytes.cjs');
require('../types/generic/typed-null.cjs');
require('../types/generic/create-placeholder.cjs');
require('../types/generic/typed-bytes.cjs');
require('../types/generic/typed-string.cjs');
require('../types/generic/typed-array.cjs');
require('../types/generic/typed-tuple.cjs');
require('../types/generic/typed-number.cjs');
require('../types/generic/typed-set.cjs');
require('../types/generic/typed-map.cjs');
require('../types/generic/typed-struct.cjs');
require('uuid');
require('js-sha256');
require('../types/generic/with-qualifier.cjs');
require('../types/generic/utils.cjs');
require('../types/generic/typed-bytes-array.cjs');
require('../types/did/onchain/typed-did/index.cjs');
require('../types/did/onchain/typed-did/did-method-key/did-method-key-public-key.cjs');
require('../utils/encoding/base-58-btc.cjs');
require('../types/generic/sized.cjs');
require('../utils/types/number.cjs');
require('../types/did/onchain/constants.cjs');
require('../types/did/onchain/typed-did/signature.cjs');
require('../types/did/onchain/typed-did/did-method-key/did-method-key-signature.cjs');
require('../types/signatures/signature-ed25519-value.cjs');
require('../types/signatures/signature-secp256k1-value.cjs');
require('../types/signatures/signature-sr25519-value.cjs');
require('../types/did/onchain/typed-did/dock-did-value.cjs');
require('../types/generic/typed-uuid.cjs');
require('../types/did/onchain/typed-did/cheqd-did.cjs');
require('./jws.cjs');
require('./crypto/common/DockCryptoSignatureProof.cjs');
require('./crypto/EcdsaSecp256k1VerificationKey2019.cjs');
require('../utils/encoding/multibase.cjs');
require('elliptic');
require('./crypto/Ed25519VerificationKey2018.cjs');
require('../keypairs/keypair-ed25519.cjs');
require('./crypto/Ed25519VerificationKey2020.cjs');
require('../types/did/onchain/did-key.cjs');
require('../types/offchain-signatures/params/index.cjs');
require('../types/offchain-signatures/params/value.cjs');
require('../types/generic/option.cjs');
require('../types/offchain-signatures/curve-type.cjs');
require('../types/offchain-signatures/params/id.cjs');
require('../types/generic/with-from-dock-id.cjs');
require('../types/offchain-signatures/public-keys/index.cjs');
require('../types/generic/with-prop.cjs');
require('../types/generic/with-props.cjs');
require('../types/offchain-signatures/public-keys/value.cjs');
require('../types/offchain-signatures/public-keys/ref.cjs');
require('../types/offchain-signatures/public-keys/id.cjs');
require('../types/did/onchain/verification-relationship.cjs');
require('../types/did/document/verification-method-ref-or-ident-ref.cjs');
require('../types/did/document/ident-ref.cjs');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var jsonld__default = /*#__PURE__*/_interopDefault(jsonld);

/**
 * @typedef {object} KeyDoc The Options to use in the function createUser.
 * @property {string} id The key's ID
 * @property {any} controller The key's controller ste
 * @property {any} type the type of key, Sr25519VerificationKey2020 or Ed25519VerificationKey2018 or EcdsaSecp256k1VerificationKey2019
 * @property {object} keypair Keypair is generated by either using polkadot-js's keyring or utils
 * @property {object} publicKey The key's public key taken from the keypair
 */

/**
 * Helper to get the key doc in a format needed for vc.js.
 * @param {string} did - DID in fully qualified form
 * @param {object} keypair - Keypair is generated by either using polkadot-js's keyring for Sr25519 and
 * Ed25519 or keypair generated with `generateEcdsaSecp256k1Keypair` for curve secp256k1.
 * @param {string} type - the type of key, Sr25519VerificationKey2020 or Ed25519VerificationKey2018 or EcdsaSecp256k1VerificationKey2019 or Bls12381G2VerificationKeyDock2022
 * @param {string} id - the ID of the key for future resolution
 * @returns {KeyDoc}
 */
function getKeyDoc(did, kp, type, id) {
  const keypair = kp instanceof keypairs_didKeypair ? kp.keyPair : kp;

  return {
    id: id || `${did}#keys-1`,
    controller: String(did),
    type: type || keypair.constructor.VerKeyType,
    keypair,
  };
}

/**
 * Get signature suite from a keyDoc
 * @param {object} keyDoc - key document containing `id`, `controller`, `type`, `privateKeyBase58` and `publicKeyBase58`
 * @returns {object} - signature suite.
 */
async function getSuiteFromKeyDoc(keyDoc, useProofValue, options) {
  // Check if passing suite directly
  if (keyDoc.verificationMethod) {
    return keyDoc;
  }

  let Cls;
  let { keypair } = keyDoc;
  switch (keyDoc.type) {
    case vc_crypto_constants.EcdsaSecp256k1VerKeyName:
      Cls = vc_crypto_EcdsaSecp256k1Signature2019;
      break;
    case vc_crypto_constants.Ed25519VerKeyName:
      Cls = vc_crypto_Ed25519Signature2018;
      break;
    case vc_crypto_constants.Ed255192020VerKeyName:
      Cls = vc_crypto_Ed25519Signature2020;
      break;
    case vc_crypto_constants.Bls12381BBSDockVerKeyName:
      Cls = vc_crypto_Bls12381BBSSignatureDock2022;
      break;
    case vc_crypto_constants.Bls12381BBS23DockVerKeyName:
      Cls = vc_crypto_Bls12381BBSSignatureDock2023;
      break;
    case vc_crypto_constants.Bls12381PSDockVerKeyName:
      Cls = vc_crypto_Bls12381PSSignatureDock2023;
      break;
    case vc_crypto_constants.Bls12381BBDT16DockVerKeyName:
      Cls = vc_crypto_Bls12381BBDT16MACDock2024;
      break;
    case 'JsonWebKey2020':
      Cls = vc_crypto_JsonWebSignature2020;
      if (!keypair) {
        keypair = await jsonWebSignature.JsonWebKey.from(keyDoc, options);
      }
      break;
    default:
      throw new Error(`Unknown key type ${keyDoc.type}.`);
  }

  return new Cls({
    ...keyDoc,
    verificationMethod: keyDoc.id,
    useProofValue,
    keyDoc,
    keypair,
  });
}

/**
 * Helper method to ensure credential is valid according to the context
 * @param credential
 */
async function expandJSONLD(credential, options = {}) {
  if (options.documentLoader && options.resolver) {
    throw new Error(
      'Passing resolver and documentLoader results in resolver being ignored, please re-factor.',
    );
  }

  const expanded = await jsonld__default.default.expand(credential, {
    ...options,
    documentLoader:
      options.documentLoader || vc_documentLoader(options.resolver),
  });
  return expanded[0];
}

function potentialToArray(a) {
  /* eslint-disable no-nested-ternary */
  return a ? (Array.isArray(a) ? a : [a]) : [];
}

/**
 * Compares a verification method reference with a key ID to determine if they are equivalent.
 * The function checks if the reference might start with `did:dock:`, and converts it to a `did:cheqd:` format for comparison.
 *
 * @param {string} ref - The verification method reference to compare.
 * @param {string} keyId - The key ID to compare against.
 * @returns {boolean} - Returns `true` if the references are equivalent, `false` otherwise.
 */
const verMethodRefsEqual = (ref, keyId) => ref === keyId
  || types_did_document_verificationMethodRef.possibleVerificationMethodRefs(ref).some((id) => id === keyId);

function getKeyFromDIDDocument(didDocument, didUrl) {
  // Ensure not already a key doc
  if (
    didDocument.publicKeyBase58
    || didDocument.publicKeyMultibase
    || didDocument.publicKeyJwk
    || (didDocument.publicKey && !Array.isArray(didDocument.publicKey))
  ) {
    return didDocument;
  }

  const possibleKeys = [
    ...potentialToArray(didDocument.verificationMethod),
    ...potentialToArray(didDocument.keyAgreement),
    ...potentialToArray(didDocument.publicKey),
  ];

  return possibleKeys.find((key) => verMethodRefsEqual(didUrl, key.id));
}

/**
 * For KVAC, public key is not present so the holder assumes that the given credential is valid.
 * Secondly, these credentials are never shared as it is with the verifier so this function returns true if the credential is
 * a KVAC, else returns undefined.
 * @param credential
 * @returns {object | undefined}
 */
function processIfKvac(credential) {
  const { proof } = credential;
  if (proof === undefined || proof.type === undefined) {
    throw new Error(
      `Credential should have a non-null type field but found ${proof.type}`,
    );
  }
  if (proof.type === vc_crypto_constants.Bls12381BBDT16MacDockName) {
    return {
      results: [
        {
          verified: true,
          proof,
          verificationMethod: {},
          purposeResult: {},
        },
      ],
      verified: true,
    };
  }
  return undefined;
}

exports.expandJSONLD = expandJSONLD;
exports.getKeyDoc = getKeyDoc;
exports.getKeyFromDIDDocument = getKeyFromDIDDocument;
exports.getSuiteFromKeyDoc = getSuiteFromKeyDoc;
exports.potentialToArray = potentialToArray;
exports.processIfKvac = processIfKvac;
exports.verMethodRefsEqual = verMethodRefsEqual;
//# sourceMappingURL=helpers.cjs.map
