/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
/* jshint node:true */
'use strict';

var KeyPair = require('./keypair');
var Policy = require('scytl-cryptopolicy');
var forge = require('node-forge');

module.exports = KeyPairGenerator;

/**
 * @class KeyPairGenerator
 * @classdesc The key pair generator API. To instantiate this object, use the
 *            method {@link AsymmetricCryptographyService.newKeyPairGenerator}.
 * @hideconstructor
 * @param {Policy}
 *            policy The cryptographic policy to use.
 * @param {SecureRandomService}
 *            secureRandomService The secure random service to use.
 */
function KeyPairGenerator(policy, secureRandomService) {
  /**
   * Generates a key pair to use for asymmetric cryptography operations.
   *
   * @function next
   * @memberof KeyPairGenerator
   * @returns {KeyPair} The generated key pair.
   */
  this.next = function() {
    if (policy.asymmetric.keyPair.encryption.algorithm ===
        Policy.options.asymmetric.keyPair.encryption.algorithm.RSA) {
      return generateRsaKeyPair(policy, secureRandomService);
    } else {
      throw new Error(
          'Key pair generation algorithm \'' +
          policy.asymmetric.keyPair.encryption.algorithm +
          '\' is not supported.');
    }
  };

  /**
   * Generates an RSA-based key pair.
   *
   * @function generateRsaKeyPairs
   * @memberof KeyPairGenerator
   * @private
   * @param {Policy}
   *            policy The cryptographic policy.
   * @param {SecureRandomService}
   *            secureRandomService The secure random service.
   * @returns {KeyPair} The key pair.
   */
  function generateRsaKeyPair(policy, secureRandomService) {
    var forgeKeyPair = forge.pki.rsa.generateKeyPair(
        policy.asymmetric.keyPair.encryption.keyLengthBits,
        policy.asymmetric.keyPair.encryption.publicExponent,
        {prng: secureRandomService.newRandomGenerator()});

    var publicKey = forge.pki.publicKeyToPem(forgeKeyPair.publicKey, 64);
    var privateKey = forge.pki.privateKeyToPem(forgeKeyPair.privateKey, 64);

    return new KeyPair(publicKey, privateKey);
  }
}
