'use strict';

var jsonWebSignature = require('@transmute/json-web-signature');
var vc_crypto_common_CustomLinkedDataSignature = require('./common/CustomLinkedDataSignature.cjs');
require('jsonld-signatures');
require('bs58');
require('base64url');
require('jsonld');
require('../../types/did/document/verification-method-ref.cjs');
require('../../types/generic/typed-enum.cjs');
require('../../utils/types/array.cjs');
require('../../utils/inheritance.cjs');
require('../../utils/types/object.cjs');
require('../../utils/types/iterable.cjs');
require('../../utils/types/set.cjs');
require('crypto');
require('../../utils/interfaces.cjs');
require('../../utils/assert.cjs');
require('../../utils/error.cjs');
require('multiformats/bases/base58');
require('varint');
require('../../utils/encoding/ss-58.cjs');
require('blake2b');
require('../../utils/types/bytes.cjs');
require('../../utils/types/string.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('../../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/public-keys/public-key.cjs');
require('../../types/public-keys/public-key-x25519-value.cjs');
require('../../types/public-keys/public-key-ed25519-value.cjs');
require('./constants.cjs');
require('../../types/public-keys/public-key-secp256k1-value.cjs');
require('../../types/public-keys/public-key-sr25519-value.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-value.cjs');
require('../../types/signatures/signature-ed25519-value.cjs');
require('../../types/signatures/signature-secp256k1-value.cjs');
require('../../types/signatures/signature.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');

const SUITE_CONTEXT_URL = 'https://w3id.org/security/suites/jws-2020/v1';

class JsonWebSignature2020 extends vc_crypto_common_CustomLinkedDataSignature.default {
  /**
   * Creates a new JsonWebSignature2020 instance
   * @constructor
   * @param {object} config - Configuration options
   */
  constructor(options = {}) {
    const {
      keypair, verifier, signer, useProofValue, verificationMethod,
    } = options;

    super({
      type: 'JsonWebSignature2020',
      LDKeyClass: jsonWebSignature.JsonWebKey,
      contextUrl: SUITE_CONTEXT_URL,
      signer: signer || (keypair && keypair.privateKey && keypair.signer()),
      // alg: keypair && keypair.publicKey && keypair.publicKey.algorithm.name,
      verifier: verifier || (keypair && keypair.verifier()),
      useProofValue,
    });

    this.requiredKeyType = 'JsonWebKey2020';
    this.verificationMethod = verificationMethod || (keypair && keypair.id);
  }

  /**
   * Adds a signature (proofValue) field to the proof object. Called by
   * LinkedDataSignature.createProof().
   *
   * @param {object} options - The options to use.
   * @param {Uint8Array} options.verifyData - Data to be signed (extracted
   *   from document, according to the suite's spec).
   * @param {object} options.proof - Proof object (containing the proofPurpose,
   *   verificationMethod, etc).
   *
   * @returns {Promise<object>} Resolves with the proof containing the signature
   *   value.
   */
  async sign({ verifyData, proof }) {
    const finalProof = { ...proof };
    finalProof.jws = await this.signer.sign({
      data: verifyData,
      detached: true,
    });
    return finalProof;
  }

  /**
   * Verifies the proof signature against the given data.
   *
   * @param {object} options - The options to use.
   * @param {Uint8Array} options.verifyData - Canonicalized hashed data.
   * @param {object} options.verificationMethod - Key object.
   * @param {object} options.proof - The proof to be verified.
   *
   * @returns {Promise<boolean>} Resolves with the verification result.
   */
  async verifySignature({ verifyData, verificationMethod, proof }) {
    const data = verifyData;
    let { verifier } = this;
    if (!verifier) {
      const key = await this.LDKeyClass.from(verificationMethod);
      verifier = key.verifier();
    }
    return verifier.verify({ data, signature: proof.jws });
  }

  /**
   * @param document {object} to be signed.
   * @param proof {object}
   * @param documentLoader {function}
   */
  async getVerificationMethod({ proof, documentLoader }) {
    let { verificationMethod } = proof;

    if (typeof verificationMethod === 'object') {
      verificationMethod = verificationMethod.id;
    }

    if (!verificationMethod) {
      throw new Error('No "verificationMethod" found in proof.');
    }

    const { document } = await documentLoader(verificationMethod);

    if (!document) {
      throw new Error(`Verification method ${verificationMethod} not found.`);
    }

    // ensure verification method has not been revoked
    if (document.revoked !== undefined) {
      throw new Error('The verification method has been revoked.');
    }

    return document;
  }
}

module.exports = JsonWebSignature2020;
//# sourceMappingURL=JsonWebSignature2020.cjs.map
