/*
 * 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 CommonTestData = require('./common-data');
var elGamal = require('scytl-elgamal');

module.exports = PlaintextEqualityProofTestData;

/**
 * Provides the data needed by the plaintext equality zero-knowledge proof of
 * knowledge unit tests.
 */
function PlaintextEqualityProofTestData() {
  var NUM_PLAINTEXT_ELEMENTS = 3;
  var PLAINTEXT_EQUALITY_PROOF_STRING_DATA =
      'Test Plaintext Equality Proof Auxilary Data';
  var OTHER_PLAINTEXT_EQUALITY_PROOF_STRING_DATA =
      PLAINTEXT_EQUALITY_PROOF_STRING_DATA + '0';
  var NUM_PLAINTEXT_EQUALITY_PROOF_PROGRESS_CHECKS =
      (NUM_PLAINTEXT_ELEMENTS * 2) + 2;

  var elGamalEncrypter = elGamal.newService().newEncrypter();

  var commonTestData = new CommonTestData();
  var group_ = commonTestData.getGroup();
  var anotherGroup_ = commonTestData.getAnotherGroup();

  var primaryPublicKey_ =
      commonTestData.generateKeyPair(group_, NUM_PLAINTEXT_ELEMENTS).publicKey;
  var secondaryPublicKey_ =
      commonTestData.generateKeyPair(group_, NUM_PLAINTEXT_ELEMENTS).publicKey;
  var anotherPrimaryPublicKey_;
  do {
    anotherPrimaryPublicKey_ =
        commonTestData.generateKeyPair(group_, NUM_PLAINTEXT_ELEMENTS)
            .publicKey;
  } while (
      anotherPrimaryPublicKey_.elements.equals(primaryPublicKey_.elements));
  var anotherSecondaryPublicKey_;
  do {
    anotherSecondaryPublicKey_ =
        commonTestData.generateKeyPair(group_, NUM_PLAINTEXT_ELEMENTS)
            .publicKey;
  } while (
      anotherSecondaryPublicKey_.elements.equals(secondaryPublicKey_.elements));
  var publicKeyWithLessElements_ =
      commonTestData.generateKeyPair(group_, (NUM_PLAINTEXT_ELEMENTS - 1))
          .publicKey;
  var publicKeyFromAnotherGroup_ =
      commonTestData.generateKeyPair(anotherGroup_, NUM_PLAINTEXT_ELEMENTS)
          .publicKey;

  var plaintext = commonTestData.generateRandomGroupElements(
      group_, NUM_PLAINTEXT_ELEMENTS);
  var anotherPlaintext;
  do {
    anotherPlaintext = commonTestData.generateRandomGroupElements(
        group_, NUM_PLAINTEXT_ELEMENTS);
  } while (anotherPlaintext.equals(plaintext));
  var plaintextWithLessElements = commonTestData.generateRandomGroupElements(
      group_, (NUM_PLAINTEXT_ELEMENTS - 1));
  var plaintextFromAnotherGroup = commonTestData.generateRandomGroupElements(
      anotherGroup_, NUM_PLAINTEXT_ELEMENTS);

  var primaryEncryptedElements_ =
      elGamalEncrypter.init(primaryPublicKey_).encrypt(plaintext, {
        saveSecret: true
      });
  var secondaryEncryptedElements_ =
      elGamalEncrypter.init(secondaryPublicKey_).encrypt(plaintext, {
        saveSecret: true
      });
  var otherPrimaryEncryptedElements_;
  do {
    otherPrimaryEncryptedElements_ =
        elGamalEncrypter.init(primaryPublicKey_).encrypt(plaintext, {
          saveSecret: true
        });
  } while (otherPrimaryEncryptedElements_.secret.equals(
               primaryEncryptedElements_.secret) ||
           otherPrimaryEncryptedElements_.phis.equals(
               primaryEncryptedElements_.phis));
  var otherSecondaryEncryptedElements_;
  do {
    otherSecondaryEncryptedElements_ =
        elGamalEncrypter.init(secondaryPublicKey_).encrypt(plaintext, {
          saveSecret: true
        });
  } while (otherSecondaryEncryptedElements_.secret.equals(
               secondaryEncryptedElements_.secret) ||
           otherSecondaryEncryptedElements_.phis.equals(
               secondaryEncryptedElements_.phis));
  var encryptedElementsWithLessElements_ =
      elGamalEncrypter.init(publicKeyWithLessElements_)
          .encrypt(plaintextWithLessElements, {saveSecret: true});
  var encryptedElementsFromAnotherGroup_ =
      elGamalEncrypter.init(publicKeyFromAnotherGroup_)
          .encrypt(plaintextFromAnotherGroup, {saveSecret: true});

  this.getGroup = function() {
    return group_;
  };

  this.getAnotherGroup = function() {
    return anotherGroup_;
  };

  this.getPrimaryPublicKey = function() {
    return primaryPublicKey_;
  };

  this.getSecondaryPublicKey = function() {
    return secondaryPublicKey_;
  };

  this.getAnotherPrimaryPublicKey = function() {
    return anotherPrimaryPublicKey_;
  };

  this.getAnotherSecondaryPublicKey = function() {
    return anotherSecondaryPublicKey_;
  };

  this.getPublicKeyWithLessElements = function() {
    return publicKeyWithLessElements_;
  };

  this.getPublicKeyFromAnotherGroup = function() {
    return publicKeyFromAnotherGroup_;
  };

  this.getPrimaryEncryptedElements = function() {
    return primaryEncryptedElements_;
  };

  this.getSecondaryEncryptedElements = function() {
    return secondaryEncryptedElements_;
  };

  this.getOtherPrimaryEncryptedElements = function() {
    return otherPrimaryEncryptedElements_;
  };

  this.getOtherSecondaryEncryptedElements = function() {
    return otherSecondaryEncryptedElements_;
  };

  this.getEncryptedElementsWithLessElements = function() {
    return encryptedElementsWithLessElements_;
  };

  this.getEncryptedElementsFromAnotherGroup = function() {
    return encryptedElementsFromAnotherGroup_;
  };

  this.getStringData = function() {
    return PLAINTEXT_EQUALITY_PROOF_STRING_DATA;
  };

  this.getOtherStringData = function() {
    return OTHER_PLAINTEXT_EQUALITY_PROOF_STRING_DATA;
  };

  this.getNumProgressChecks = function() {
    return NUM_PLAINTEXT_EQUALITY_PROOF_PROGRESS_CHECKS;
  };
}
