/*
 * 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.ov.mixing.commons.beans.proofs;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.scytl.ov.mixing.commons.proofs.bg.commitments.CommitmentParams;
import com.scytl.ov.mixing.commons.proofs.bg.commitments.PublicCommitment;

/**
 * This class encapsulates the proofs that are generated by the {@link ShuffleProofGenerator}.
 */
public class BayerGrothProof implements Proof {

    private final PublicCommitment[] initialMessage;

    private final PublicCommitment[] firstAnswer;

    private final ShuffleProofSecondAnswer secondAnswer;

    private final CommitmentParams commitmentParams;

    @JsonCreator
    public BayerGrothProof(@JsonProperty("initialMessage") final PublicCommitment[] initialMessage,
            @JsonProperty("firstAnswer") final PublicCommitment[] firstAnswer,
            @JsonProperty("secondAnswer") final ShuffleProofSecondAnswer secondAnswer,
            @JsonProperty("commitmentParams") final CommitmentParams commitmentParams) {

        this.initialMessage = initialMessage;
        this.firstAnswer = firstAnswer;
        this.secondAnswer = secondAnswer;
        this.commitmentParams = commitmentParams;
    }

    private BayerGrothProof(final Builder builder) {
    	this.initialMessage = builder.iniMessage;
    	this.firstAnswer = builder.fAnswer;
    	this.secondAnswer = builder.sAnswer;
    	this.commitmentParams = builder.commParams;
    }

    public PublicCommitment[] getInitialMessage() {
        return initialMessage;
    }

    public PublicCommitment[] getFirstAnswer() {
        return firstAnswer;
    }

    public ShuffleProofSecondAnswer getSecondAnswer() {
        return secondAnswer;
    }

    public CommitmentParams getCommitmentParams() {
        return commitmentParams;
    }

    public static class Builder {

        private PublicCommitment[] iniMessage;

        private PublicCommitment[] fAnswer;

        private ShuffleProofSecondAnswer sAnswer;

        private CommitmentParams commParams;

        public Builder withInitialMessage(final PublicCommitment[] initialMessage) {
        	this.iniMessage = initialMessage;
            return this;
        }

        public Builder withFirstAnswer(final PublicCommitment[] firstAnswer) {
        	this.fAnswer = firstAnswer;
            return this;
        }

        public Builder withSecondAnswer(final ShuffleProofSecondAnswer secondAnswer) {
        	this.sAnswer = secondAnswer;
            return this;
        }

        public Builder withCommitmentParams(final CommitmentParams commitmentParams) {
        	this.commParams = commitmentParams;
            return this;
        }

        public BayerGrothProof build() {
            checkValues();
            return new BayerGrothProof(this);
        }

        private void checkValues() {
            if (iniMessage == null) {
                throw new IllegalStateException("Initial message cannot be null");
            }
            if (fAnswer == null) {
                throw new IllegalStateException("First answer cannot be null");
            }
            if (sAnswer == null) {
                throw new IllegalStateException("Second answer cannot be null");
            }
            if (commParams == null) {
                throw new IllegalStateException("Commitment params cannot be null");
            }
        }
    }
}
