/*
 * 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 SchnorrProofTestData = require('../data/schnorr-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 secret_;
  var secretFromAnotherGroup_;
  var gamma_;
  var gammaFromAnotherGroup_;
  var voterId_;
  var electionId_;
  var callback_;
  var nonObject_;
  var emptyObject_;
  var nonNumber_;
  var nonPositiveNumber_;
  var nonString_;
  var emptyString_;
  var nonFunction_;
  var nonAuxiliaryData_;
  var nonProofObject_;
  var proofHandler_;
  var proof_;

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

    var testData = new SchnorrProofTestData();
    group_ = testData.getGroup();
    anotherGroup_ = testData.getAnotherGroup();
    secret_ = testData.getSecret();
    secretFromAnotherGroup_ = testData.getSecretFromAnotherGroup();
    gamma_ = testData.getGamma();
    gammaFromAnotherGroup_ = testData.getGammaFromAnotherGroup();
    voterId_ = testData.getVoterId();
    electionId_ = testData.getElectionId();

    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();
    emptyString_ = validationTestData.getEmptyString();
    nonFunction_ = validationTestData.getNonFunction();
    nonAuxiliaryData_ = validationTestData.getNonAuxiliaryData();
    nonProofObject_ = validationTestData.getNonProofObject();

    proofHandler_ = proofService_.newSchnorrProofHandler(group_);
    proof_ = proofHandler_.generate(secret_, gamma_);
  });

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

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

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

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

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

      it('throw an error when generating a Schnorr proof, using an invalid secret',
         function() {
           expect(function() {
             proofHandler_.generate(undefined, gamma_);
           }).toThrow();

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

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

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

           expect(function() {
             proofHandler_.generate(secretFromAnotherGroup_, gamma_);
           }).toThrow();
         });

      it('throw an error when generating a Schnorr proof, using an invalid gamma element',
         function() {
           expect(function() {
             proofHandler_.generate(secret_, undefined);
           }).toThrow();

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

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

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

           expect(function() {
             proofHandler_.generate(secret_, gammaFromAnotherGroup_);
           }).toThrow();
         });

      it('throw an error when generating a Schnorr proof, using invalid optional data',
         function() {
           expect(function() {
             proofHandler_.generate(secret_, gamma_, {data: nonAuxiliaryData_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(
                 secret_, gamma_,
                 {voterId: nonString_, electionId: electionId_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(
                 secret_, gamma_, {voterId: voterId_, electionId: nonString_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(
                 secret_, gamma_,
                 {voterId: emptyString_, electionId: electionId_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(
                 secret_, gamma_,
                 {voterId: voterId_, electionId: emptyString_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(secret_, gamma_, {voterId: voterId_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(secret_, gamma_, {electionId: electionId_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(
                 secret_, gamma_, {preComputation: nonObject_});
           }).toThrow();

           expect(function() {
             proofHandler_.generate(
                 secret_, gamma_, {preComputation: nonProofObject_});
           }).toThrow();
         });

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

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

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

      it('throw an error when verifying a Schnorr proof, using an invalid gamma element',
         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_, gammaFromAnotherGroup_);
           }).toThrow();
         });

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

           expect(function() {
             proofHandler_.verify(
                 proof_, gamma_,
                 {voterId: nonString_, electionId: electionId_});
           }).toThrow();

           expect(function() {
             proofHandler_.verify(
                 proof_, gamma_, {voterId: voterId_, electionId: nonString_});
           }).toThrow();

           expect(function() {
             proofHandler_.verify(
                 proof_, gamma_,
                 {voterId: emptyString_, electionId: electionId_});
           }).toThrow();

           expect(function() {
             proofHandler_.verify(
                 proof_, gamma_, {voterId: voterId_, electionId: emptyString_});
           }).toThrow();

           expect(function() {
             proofHandler_.verify(proof_, gamma_, {voterId: voterId_});
           }).toThrow();

           expect(function() {
             proofHandler_.verify(proof_, gamma_, {electionId: electionId_});
           }).toThrow();
         });

      it('throw an error when measuring Schnorr 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();
         });
    });
  });
});
