/*
 * 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.channel.cc.commons.keymanagement;

import static java.util.Objects.requireNonNull;

import javax.annotation.Nonnegative;

import com.scytl.cryptolib.elgamal.cryptoapi.EncryptionParameters;

/**
 * Choice code keys specification.
 */
public final class ChoiceCodeKeysSpec {
    private final String electionEventId;

    private final String verificationCardSetId;

    private final EncryptionParameters parameters;

    private final int generationLength;

    private final int decryptionLength;

    private ChoiceCodeKeysSpec(String electionEventId,
            String verificationCardSetId, EncryptionParameters parameters,
            int generationLength, int decryptionLength) {
        this.electionEventId = electionEventId;
        this.verificationCardSetId = verificationCardSetId;
        this.parameters = parameters;
        this.generationLength = generationLength;
        this.decryptionLength = decryptionLength;
    }

    /**
     * Returns the decryption keys length.
     * 
     * @return the decryption keys length.
     */
    @Nonnegative
    public int decryptionLength() {
        return decryptionLength;
    }

    /**
     * Returns the election event identifier.
     * 
     * @return the election event identifier.
     */
    public String electionEventId() {
        return electionEventId;
    }

    /**
     * Returns the generation keys length.
     * 
     * @return the generation keys length.
     */
    @Nonnegative
    public int generationLength() {
        return generationLength;
    }

    /**
     * Returns the parameters.
     * 
     * @return the parameters.
     */
    public EncryptionParameters parameters() {
        return parameters;
    }

    @Override
    public String toString() {
        return "ChoiceCodeKeysSpec [electionEventId=" + electionEventId
            + ", verificationCardSetId=" + verificationCardSetId
            + ", parameters=" + parameters + ", generationLength="
            + generationLength + ", decryptionLength=" + decryptionLength
            + "]";
    }

    /**
     * Returns the verification card set identifier.
     * 
     * @return the verification card set identifier.
     */
    public String verificationCardSetId() {
        return verificationCardSetId;
    }

    /**
     * Builder for creating {@link ChoiceCodeKeysSpec} instances.
     */
    public static final class Builder {
        private String electionEventId;

        private String verificationCardSetId;

        private EncryptionParameters parameters;

        private int generationLength;

        private int decryptionLength;

        /**
         * Builds a new {@link MixingKeysSpec} instance.
         * 
         * @return a new instance.
         */
        public ChoiceCodeKeysSpec build() {
            requireNonNull(electionEventId, "Election event id is null.");
            requireNonNull(verificationCardSetId,
                "Verification card set id is null.");
            requireNonNull(parameters, "Paraeters are null.");
            if (generationLength < 0) {
                throw new IllegalArgumentException(
                    "Generation key length is negative.");
            }
            if (decryptionLength < 0) {
                throw new IllegalArgumentException(
                    "Decryption key length is negative.");
            }
            return new ChoiceCodeKeysSpec(electionEventId,
                verificationCardSetId, parameters, generationLength,
                decryptionLength);
        }

        /**
         * Sets the decryption keys length.
         * 
         * @param decryptionLength
         *            the length
         * @return this instance.
         */
        public Builder setDecryptionLength(
                @Nonnegative int decryptionLength) {
            this.decryptionLength = decryptionLength;
            return this;
        }

        /**
         * Sets the election event identifier.
         * 
         * @param electionEventId
         *            the election event identifier
         * @return this instance.
         */
        public Builder setElectionEventId(String electionEventId) {
            this.electionEventId = electionEventId;
            return this;
        }

        /**
         * Sets the generation keys length.
         * 
         * @param generationLength
         *            the length
         * @return this instance.
         */
        public Builder setGenerationLength(
                @Nonnegative int generationLength) {
            this.generationLength = generationLength;
            return this;
        }

        /**
         * Sets the parameters.
         * 
         * @param parameters
         *            the parameters
         * @return this instance.
         */
        public Builder setParameters(EncryptionParameters parameters) {
            this.parameters = parameters;
            return this;
        }

        /**
         * Sets the verification card set identifier.
         * 
         * @param verificationCardSetId
         *            the verification card set identifier
         * @return this instance.
         */
        public Builder setVerificationCardSetId(
                String verificationCardSetId) {
            this.verificationCardSetId = verificationCardSetId;
            return this;
        }
    }
}
