/*
 * 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 PlaintextExponentEqualityProofTestData =
    require('../data/plaintext-exponent-equality-proof-data');
var ProgressMeterTestData = require('../data/progress-meter-data');
var ValidationTestData = require('../data/validation-data');
var zkProof = require('../../lib/index');

describe('The zero-knowledge proof module should be able to ...', function() {
  var proofService_;

  var group_;
  var anotherGroup_;
  var firstSecret_;
  var secondSecret_;
  var firstSecretFromAnotherGroup_;
  var secondSecretFromAnotherGroup_;
  var baseElements_;
  var lessBaseElements_;
  var baseElementsFromAnotherGroup_;
  var ciphertext_;
  var ciphertextWithLessElements_;
  var ciphertextFromAnotherGroup_;
  var callback_;
  var nonObject_;
  var emptyObject_;
  var nonNumber_;
  var nonPositiveNumber_;
  var nonString_;
  var nonArray_;
  var emptyArray_;
  var nonObjectArray_;
  var nonFunction_;
  var nonAuxiliaryData_;
  var nonProofObject_;
  var proofHandler_;
  var proof_;

  beforeAll(function() {
    proofService_ = zkProof.newService();

    var testData = new PlaintextExponentEqualityProofTestData();
    group_ = testData.getGroup();
    anotherGroup_ = testData.getAnotherGroup();
    firstSecret_ = testData.getFirstSecret();
    secondSecret_ = testData.getSecondSecret();
    firstSecretFromAnotherGroup_ = testData.getFirstSecretFromAnotherGroup();
    secondSecretFromAnotherGroup_ = testData.getSecondSecretFromAnotherGroup();
    baseElements_ = testData.getBaseElements();
    lessBaseElements_ = testData.getLessBaseElements();
    baseElementsFromAnotherGroup_ = testData.getBaseElementsFromAnotherGroup();
    ciphertext_ = testData.getCiphertext();
    ciphertextWithLessElements_ = testData.getCiphertextWithLessElements();
    ciphertextFromAnotherGroup_ = testData.getCiphertextFromAnotherGroup();

    var progressMeterTestData = new ProgressMeterTestData();
    callback_ = progressMeterTestData.progressCallback;

    var validationTestData = new ValidationTestData();
    nonObject_ = validationTestData.getNonObject();
    emptyObject_ = validationTestData.getEmptyObject();
    nonNumber_ = validationTestData.getNonNumber();
    nonPositiveNumber_ = validationTestData.getNonPositiveNumber();
    nonString_ = validationTestData.getNonString();
    nonArray_ = validationTestData.getNonArray();
    emptyArray_ = validationTestData.getEmptyArray();
    nonObjectArray_ = validationTestData.getNonObjectArray();
    nonFunction_ = validationTestData.getNonFunction();
    nonAuxiliaryData_ = validationTestData.getNonAuxiliaryData();
    nonProofObject_ = validationTestData.getNonProofObject();

    proofHandler_ =
        proofService_.newPlaintextExponentEqualityProofHandler(group_).init(
            baseElements_);
    proof_ = proofHandler_.generate(firstSecret_, secondSecret_, ciphertext_);
  });

  beforeEach(function() {
    proofHandler_ =
        proofService_.newPlaintextExponentEqualityProofHandler(group_).init(
            baseElements_);
  });

  describe('create a zero-knowledge proof service that should be able to ..', function() {
    describe(
        'create a plaintext exponent equality proof handler that should be able to',
        function() {
          it('throw an error when being created, using invalid input data',
             function() {
               expect(function() {
                 proofService_.newPlaintextExponentEqualityProofHandler();
               }).toThrow();

               expect(function() {
                 proofService_.newPlaintextExponentEqualityProofHandler(
                     undefined);
               }).toThrow();

               expect(function() {
                 proofService_.newPlaintextExponentEqualityProofHandler(null);
               }).toThrow();

               expect(function() {
                 proofService_.newPlaintextExponentEqualityProofHandler(
                     nonObject_);
               }).toThrow();

               expect(function() {
                 proofService_.newPlaintextExponentEqualityProofHandler(
                     emptyObject_);
               }).toThrow();
             });

          it('throw an error when initializing a plaintext exponent equality proof, using invalid input data',
             function() {
               expect(function() {
                 proofHandler_.init(undefined);
               }).toThrow();

               expect(function() {
                 proofHandler_.init(null);
               }).toThrow();

               expect(function() {
                 proofHandler_.init(nonArray_);
               }).toThrow();

               expect(function() {
                 proofHandler_.init(emptyArray_);
               }).toThrow();

               expect(function() {
                 proofHandler_.init(nonObjectArray_);
               }).toThrow();

               expect(function() {
                 proofHandler_.init(baseElementsFromAnotherGroup_);
               }).toThrow();
             });

          it('throw an error when generating a plaintext exponent equality proof, using an invalid first secret',
             function() {
               expect(function() {
                 proofHandler_.generate(undefined, secondSecret_, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(null, secondSecret_, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(nonObject_, secondSecret_, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     emptyObject_, secondSecret_, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecretFromAnotherGroup_, secondSecret_, ciphertext_);
               }).toThrow();
             });

          it('throw an error when generating a plaintext exponent equality proof, using an invalid second secret',
             function() {
               expect(function() {
                 proofHandler_.generate(firstSecret_, undefined, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(firstSecret_, null, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(firstSecret_, nonObject_, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, emptyObject_, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecretFromAnotherGroup_, ciphertext_);
               }).toThrow();
             });

          it('throw an error when generating a plaintext exponent equality proof, using an invalid ciphertext',
             function() {
               expect(function() {
                 proofHandler_.generate(firstSecret_, secondSecret_, undefined);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(firstSecret_, secondSecret_, null);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecret_, nonObject_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecret_, emptyObject_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecret_, ciphertextWithLessElements_);
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecret_, ciphertextFromAnotherGroup_);
               }).toThrow();
             });

          it('throw an error when generating a plaintext exponent equality proof, using invalid optional data',
             function() {
               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecret_, ciphertext_,
                     {data: nonAuxiliaryData_});
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecret_, ciphertext_,
                     {preComputation: nonObject_});
               }).toThrow();

               expect(function() {
                 proofHandler_.generate(
                     firstSecret_, secondSecret_, ciphertext_,
                     {preComputation: nonProofObject_});
               }).toThrow();
             });

          it('throw an error when verifying a plaintext exponent equality proof, using an invalid proof',
             function() {
               expect(function() {
                 proofHandler_.verify(undefined, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.verify(null, ciphertext_);
               }).toThrow();

               expect(function() {
                 proofHandler_.verify(nonProofObject_, ciphertext_);
               }).toThrow();
             });

          it('throw an error when verifying a plaintext exponent equality proof, using an invalid ciphertext',
             function() {
               expect(function() {
                 proofHandler_.verify(proof_, undefined);
               }).toThrow();

               expect(function() {
                 proofHandler_.verify(proof_, null);
               }).toThrow();

               expect(function() {
                 proofHandler_.verify(proof_, nonObject_);
               }).toThrow();

               expect(function() {
                 proofHandler_.verify(proof_, emptyObject_);
               }).toThrow();

               expect(function() {
                 proofHandler_.verify(proof_, ciphertextWithLessElements_);
               }).toThrow();

               expect(function() {
                 proofHandler_.verify(proof_, ciphertextFromAnotherGroup_);
               }).toThrow();
             });

          it('throw an error when verifying a plaintext exponent equality proof, using invalid optional data',
             function() {
               expect(function() {
                 proofHandler_.verify(
                     proof_, ciphertext_, {data: nonAuxiliaryData_});
               }).toThrow();
             });

          it('throw an error when measuring plaintext exponent equality proof progress, using invalid input data',
             function() {
               expect(function() {
                 proofHandler_.measureProgress();
               }).toThrow();

               expect(function() {
                 proofHandler_.measureProgress(undefined);
               }).toThrow();

               expect(function() {
                 proofHandler_.measureProgress(null);
               }).toThrow();

               expect(function() {
                 proofHandler_.measureProgress(nonFunction_);
               }).toThrow();

               expect(function() {
                 proofHandler_.measureProgress(callback_, null);
               }).toThrow();

               expect(function() {
                 proofHandler_.measureProgress(callback_, nonNumber_);
               }).toThrow();

               expect(function() {
                 proofHandler_.measureProgress(callback_, nonPositiveNumber_);
               }).toThrow();
             });
        });
  });
});
