/*
 * 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
 */
/* global require */
/* global OV */

module.exports = (function() {

    'use strict';

    var XMLHttpRequest = XMLHttpRequest || require('xhr2');
    var Q = require('q');
    var config = require('./config.js');
    var session = require('./session.js');

    var createConfirmRequest = function(ballotCastingKey) {

        // create confirmation message

        var confirmationKey;

        confirmationKey = OV.generateConfirmationKey(
            ballotCastingKey,
            session('encParams'),
            session('verificationCardSecret'));

        // sign confirmation message

        var dataToSign = [
            confirmationKey,
            session('authenticationToken').signature,
            session('votingCardId'),
            config('electionEventId')
        ];
        var confirmationKeySignature = OV.signData(
            dataToSign, session('credentials').voterPrivateKey);

        // send confirmation

        return {
            credentialId: session('credentials').credentialId,
            confirmationMessage: {
                confirmationKey: confirmationKey,
                signature: confirmationKeySignature
            },
            certificate: session('credentials').certificate
        };
    };
	
	var JSONparse = function(response) {

        var ret;
        try {
            ret = JSON.parse(response);
        } catch (ignore) {
            ret = {
                error: response
            };
        }
        return ret;
    };

	var processConfirmResponse = function(confirmResponse) {

        return OV.parseCastResponse(confirmResponse,
            session('credentials').certificate,
            session('verificationCardSet').data.voteCastCodeSignerCert,
            session('certificates')['authenticationTokenSignerCert'],
            session('ballotBoxCert'),
            session('votingCardId'),
            config('electionEventId'),
            session('verificationCardId'));
    };
	
	// generate and send confirmationmessage

    var castVote = function(ballotCastingKey) {

        var deferred = Q.defer();

        var reqData = createConfirmRequest(ballotCastingKey);

        // send confirmation

        var endpoint = config('endpoints.confirmations')
            .replace('{tenantId}', config('tenantId'))
            .replace('{electionEventId}', config('electionEventId'))
            .replace('{votingCardId}', session('votingCardId'));


        var xhr = new XMLHttpRequest();
        xhr.open('POST', config('host') + endpoint);
        xhr.onreadystatechange = function() {

            var response;

            if (xhr.readyState === 4) {
                if (xhr.status === 200) {

                    response = JSONparse(this.responseText);
                    if (response.valid) {

                        var result;
                        try {
                            result = processConfirmResponse(response);
                            deferred.resolve(result);
                        } catch (e) {
                            deferred.reject(e.message);
                        }

                    } else {
                        if (response.validationError) {
                            deferred.reject(response);
                        } else {
                            deferred.reject('invalid vote');
                        }
                    }
                } else {
                    var resp = this.responseText ? JSONparse(this.responseText) : null;
                    if (resp && resp.validationError) {
                        deferred.reject(resp);
                    } else {
                        deferred.reject(xhr.status);
                    }
                }
            }
        };
        xhr.onerror = function() {
            try {
                deferred.reject(xhr.status);
            } catch (e) {
				//This block is intentionally left blank
			}
        };
        xhr.setRequestHeader('Accept', 'application/json');
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.setRequestHeader('authenticationToken', JSON.stringify(session('authenticationToken')));
        xhr.send(JSON.stringify(reqData));

        return deferred.promise;
    };

   
    return {
        castVote: castVote,
        createConfirmRequest: createConfirmRequest,
        processConfirmResponse: processConfirmResponse
    };

}());
