/*
 * 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
 */
package com.scytl.products.ov.commons.dto;

import com.scytl.products.ov.commons.beans.domain.model.messaging.SafeStreamDeserializationException;
import static com.scytl.products.ov.commons.safestream.StreamSerializableUtil.retrieveBigIntegerValueWithNullCheck;
import static com.scytl.products.ov.commons.safestream.StreamSerializableUtil.retrieveStringValueWithNullCheck;
import static com.scytl.products.ov.commons.safestream.StreamSerializableUtil.storeBigIntegerValueWithNullCheck;
import static com.scytl.products.ov.commons.safestream.StreamSerializableUtil.storeStringValueWithNullCheck;

import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import org.msgpack.core.MessageFormat;
import org.msgpack.core.MessagePacker;
import org.msgpack.core.MessageUnpacker;

import com.scytl.products.ov.commons.beans.domain.model.messaging.StreamSerializable;
import com.scytl.products.ov.commons.beans.domain.model.messaging.StreamSerializableClassType;

public class PartialCodesInput implements StreamSerializable {

    private List<BigInteger> partialCodesElements;

    private BallotCastingKeyVerificationInput ballotCastingKeyVerificationInput;

    private ChoiceCodesVerificationInput choiceCodesVerificationInput;

    public List<BigInteger> getPartialCodesElements() {
        return partialCodesElements;
    }

    public void setPartialCodesElements(List<BigInteger> partialCodesElements) {
        this.partialCodesElements = partialCodesElements;
    }

    public BallotCastingKeyVerificationInput getBallotCastingKeyVerificationInput() {
        return ballotCastingKeyVerificationInput;
    }

    public void setBallotCastingKeyVerificationInput(
            BallotCastingKeyVerificationInput ballotCastingKeyVerificationInput) {
        this.ballotCastingKeyVerificationInput = ballotCastingKeyVerificationInput;
    }

    public ChoiceCodesVerificationInput getChoiceCodesVerificationInput() {
        return choiceCodesVerificationInput;
    }

    public void setChoiceCodesVerificationInput(ChoiceCodesVerificationInput choiceCodesVerificationInput) {
        this.choiceCodesVerificationInput = choiceCodesVerificationInput;
    }

    @Override
    public void serialize(MessagePacker packer) throws IOException {
        if(partialCodesElements == null) {
            packer.packNil();
        } else {
            packer.packArrayHeader(partialCodesElements.size());
            for (BigInteger bigInteger : partialCodesElements) {
                storeBigIntegerValueWithNullCheck(packer, bigInteger);
            }
        }
        
        if(ballotCastingKeyVerificationInput == null) {
            packer.packNil();
        } else {
            storeStringValueWithNullCheck(packer, ballotCastingKeyVerificationInput.getConfirmationMessage());
            storeStringValueWithNullCheck(packer, ballotCastingKeyVerificationInput.getVotingCardId());
        }
        if(choiceCodesVerificationInput == null) {
            packer.packNil();
        } else {
            storeStringValueWithNullCheck(packer, choiceCodesVerificationInput.getCompressesedChoiceCodesEncryptionPK());
            storeStringValueWithNullCheck(packer, choiceCodesVerificationInput.getElGamalElectoralPublicKey());
            storeStringValueWithNullCheck(packer, choiceCodesVerificationInput.getVote());
        }
    }


    @Override
    public void deserialize(MessageUnpacker unpacker) throws SafeStreamDeserializationException {
        try {
            if (unpacker.tryUnpackNil()) {
                this.partialCodesElements = null;
            } else {
                int listSize = unpacker.unpackArrayHeader();
                partialCodesElements = new ArrayList<>(listSize);
                for (int i = 0; i < listSize; i++) {
                    partialCodesElements.add(retrieveBigIntegerValueWithNullCheck(unpacker));
                }
            }

            if (MessageFormat.NIL.equals(unpacker.getNextFormat())) {
                ballotCastingKeyVerificationInput = null;
                unpacker.unpackNil();
            } else {
                ballotCastingKeyVerificationInput = new BallotCastingKeyVerificationInput();
                ballotCastingKeyVerificationInput.setConfirmationMessage(retrieveStringValueWithNullCheck(unpacker));
                ballotCastingKeyVerificationInput.setVotingCardId(retrieveStringValueWithNullCheck(unpacker));
            }
            if (MessageFormat.NIL.equals(unpacker.getNextFormat())) {
                choiceCodesVerificationInput = null;
                unpacker.unpackNil();
            } else {
                choiceCodesVerificationInput = new ChoiceCodesVerificationInput();
                choiceCodesVerificationInput.setCompressesedChoiceCodesEncryptionPK(retrieveStringValueWithNullCheck(unpacker));
                choiceCodesVerificationInput.setElGamalElectoralPublicKey(retrieveStringValueWithNullCheck(unpacker));
                choiceCodesVerificationInput.setVote(retrieveStringValueWithNullCheck(unpacker));
            }
        } catch (IOException e) {
            throw new SafeStreamDeserializationException(e);
        }
    }

    @Override
    public StreamSerializableClassType type() {
        return StreamSerializableClassType.PARTIAL_CODES_INPUT;
    }

}
