// Licensed under the Apache License, Version 2.0 (the "License");
//
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

goog.module('tink.subtle.EciesAeadHkdfHybridEncrypt');

const Bytes = goog.require('tink.subtle.Bytes');
const EciesAeadHkdfDemHelper = goog.require('tink.subtle.EciesAeadHkdfDemHelper');
const EciesHkdfKemSender = goog.require('tink.subtle.EciesHkdfKemSender');
const EllipticCurves = goog.require('tink.subtle.EllipticCurves');
const HybridEncrypt = goog.require('tink.HybridEncrypt');
const SecurityException = goog.require('tink.exception.SecurityException');

/**
 * Implementation of ECIES AEAD HKDF hybrid encryption.
 *
 * @implements {HybridEncrypt}
 * @protected
 * @final
 */
class EciesAeadHkdfHybridEncrypt {
  /**
   * @param {!EciesHkdfKemSender} kemSender
   * @param {string} hkdfHash the name of the HMAC algorithm, accepted names
   *     are: SHA-1, SHA-256 and SHA-512.
   * @param {!EllipticCurves.PointFormatType} pointFormat
   * @param {!EciesAeadHkdfDemHelper} demHelper
   * @param {!Uint8Array=} opt_hkdfSalt
   */
  constructor(kemSender, hkdfHash, pointFormat, demHelper, opt_hkdfSalt) {
    // TODO(thaidn): do we actually need these null checks?
    if (!kemSender) {
      throw new SecurityException('KEM sender has to be non-null.');
    }
    if (!hkdfHash) {
      throw new SecurityException('HMAC algorithm has to be non-null.');
    }
    if (!pointFormat) {
      throw new SecurityException('Point format has to be non-null.');
    }
    if (!demHelper) {
      throw new SecurityException('DEM helper has to be non-null.');
    }

    /** @private @const {!EciesHkdfKemSender} */
    this.kemSender_ = kemSender;
    /** @private @const {string} */
    this.hkdfHash_ = hkdfHash;
    /** @private @const {!EllipticCurves.PointFormatType} */
    this.pointFormat_ = pointFormat;
    /** @private @const {!EciesAeadHkdfDemHelper} */
    this.demHelper_ = demHelper;
    /** @private @const {!Uint8Array|undefined} */
    this.hkdfSalt_ = opt_hkdfSalt;
  }

  /**
   * @param {!webCrypto.JsonWebKey} recipientPublicKey
   * @param {string} hkdfHash the name of the HMAC algorithm, accepted names
   *     are: SHA-1, SHA-256 and SHA-512.
   * @param {!EllipticCurves.PointFormatType} pointFormat
   * @param {!EciesAeadHkdfDemHelper} demHelper
   * @param {!Uint8Array=} opt_hkdfSalt
   *
   * @return {!Promise.<!HybridEncrypt>}
   */
  static async newInstance(
      recipientPublicKey, hkdfHash, pointFormat, demHelper, opt_hkdfSalt) {
    if (!recipientPublicKey) {
      throw new SecurityException('Recipient public key has to be non-null.');
    }
    if (!hkdfHash) {
      throw new SecurityException('HMAC algorithm has to be non-null.');
    }
    if (!pointFormat) {
      throw new SecurityException('Point format has to be non-null.');
    }
    if (!demHelper) {
      throw new SecurityException('DEM helper has to be non-null.');
    }

    const kemSender = await EciesHkdfKemSender.newInstance(recipientPublicKey);
    return new EciesAeadHkdfHybridEncrypt(
        kemSender, hkdfHash, pointFormat, demHelper, opt_hkdfSalt);
  }

  /**
   * Encrypts plaintext using opt_contextInfo as info parameter of the
   * underlying HKDF.
   *
   * @override
   */
  async encrypt(plaintext, opt_contextInfo) {
    // Variable hkdfInfo is not optional for encapsulate method. Thus it
    // should be an empty array in case that it is not defined by caller of this
    // method.
    if (!opt_contextInfo) {
      opt_contextInfo = new Uint8Array(0);
    }

    const keySizeInBytes = this.demHelper_.getDemKeySizeInBytes();
    const kemKey = await this.kemSender_.encapsulate(
        keySizeInBytes, this.pointFormat_, this.hkdfHash_, opt_contextInfo,
        this.hkdfSalt_);
    const aead = await this.demHelper_.getAead(kemKey['key']);

    const ciphertextBody = await aead.encrypt(plaintext);
    const header = kemKey['token'];

    return Bytes.concat(header, ciphertextBody);
  }
}

exports = EciesAeadHkdfHybridEncrypt;
