/*
 * 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 = OrProofTestData;

/**
 * Provides the data needed by the OR zero-knowledge proof of knowledge unit
 * tests.
 */
function OrProofTestData() {
  var NUM_OR_ELEMENTS = 5;
  var OR_PROOF_STRING_DATA = 'Test OR Proof Auxilary Data';
  var OTHER_OR_PROOF_STRING_DATA = OR_PROOF_STRING_DATA + '0';
  var NUM_OR_PROOF_PROGRESS_CHECKS = NUM_OR_ELEMENTS * 2;

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

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

  var publicKey_ = commonTestData.generateKeyPair(group_, 1).publicKey;
  var anotherPublicKey_;
  do {
    anotherPublicKey_ = commonTestData.generateKeyPair(group_, 1).publicKey;
  } while (anotherPublicKey_.elements.equals(publicKey_.elements));
  var publicKeyWithTooManyElements_ =
      commonTestData.generateKeyPair(group_, 2).publicKey;
  var publicKeyFromAnotherGroup_ =
      commonTestData.generateKeyPair(anotherGroup_, 1).publicKey;

  var index_ = commonTestData.generateRandomInteger(0, (NUM_OR_ELEMENTS - 1));
  var tooSmallIndex_ = -1;
  var tooLargeIndex_ = NUM_OR_ELEMENTS;

  var elements_ =
      commonTestData.generateRandomGroupElements(group_, NUM_OR_ELEMENTS);
  var elementsWithDifferentIndexElement_;
  do {
    elementsWithDifferentIndexElement_ =
        commonTestData.generateRandomGroupElements(group_, NUM_OR_ELEMENTS);
  } while (
      elementsWithDifferentIndexElement_[index_].equals(elements_[index_]));
  var tooFewElements_ = commonTestData.generateRandomGroupElements(group_, 1);
  var elementsFromAnotherGroup_ = commonTestData.generateRandomGroupElements(
      anotherGroup_, NUM_OR_ELEMENTS);

  var encryptedElements_ =
      elGamalEncrypter.init(publicKey_).encrypt([elements_[index_]], {
        saveSecret: true
      });
  var otherencryptedElements_ =
      elGamalEncrypter.init(anotherPublicKey_).encrypt([elements_[index_]], {
        saveSecret: true
      });
  var encryptedElementsWithTooManyElements_ =
      elGamalEncrypter.init(publicKeyWithTooManyElements_)
          .encrypt([elements_[0], elements_[1]], {saveSecret: true});
  var encryptedElementsFromAnotherGroup_ =
      elGamalEncrypter.init(publicKeyFromAnotherGroup_)
          .encrypt([elementsFromAnotherGroup_[index_]], {saveSecret: true});

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

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

  this.getPublicKey = function() {
    return publicKey_;
  };

  this.getAnotherPublicKey = function() {
    return anotherPublicKey_;
  };

  this.getPublicKeyWithTooManyElements = function() {
    return publicKeyWithTooManyElements_;
  };

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

  this.getIndex = function() {
    return index_;
  };

  this.getTooSmallIndex = function() {
    return tooSmallIndex_;
  };

  this.getTooLargeIndex = function() {
    return tooLargeIndex_;
  };

  this.getNumElements = function() {
    return NUM_OR_ELEMENTS;
  };

  this.getElements = function() {
    return elements_;
  };

  this.getElementsWithDifferentIndexElement = function() {
    return elementsWithDifferentIndexElement_;
  };

  this.getTooFewElements = function() {
    return tooFewElements_;
  };

  this.getElementsFromAnotherGroup = function() {
    return elementsFromAnotherGroup_;
  };

  this.getEncryptedElements = function() {
    return encryptedElements_;
  };

  this.getOtherEncryptedElements = function() {
    return otherencryptedElements_;
  };

  this.getEncryptedElementsWithTooManyElements = function() {
    return encryptedElementsWithTooManyElements_;
  };

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

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

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

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