/*
 * 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;

/**
 * Mixing keys specification.
 */
public final class MixingKeysSpec {
    private final String electionEventId;

    private final String electoralAuthorityId;

    private final EncryptionParameters parameters;

    private final int length;

    private MixingKeysSpec(String electionEventId,
            String electoralAuthorityId, EncryptionParameters parameters,
            int length) {
        this.electionEventId = electionEventId;
        this.electoralAuthorityId = electoralAuthorityId;
        this.parameters = parameters;
        this.length = length;
    }

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

    /**
     * Returns the electoral authority identifier.
     * 
     * @return the electoral authority identifier.
     */
    public String electoralAuthorityId() {
        return electoralAuthorityId;
    }

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

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

    @Override
    public String toString() {
        return "MixingKeysSpec [electionEventId=" + electionEventId
            + ", electoralAuthorityId=" + electoralAuthorityId
            + ", parameters=" + parameters + ", length=" + length + "]";
    }

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

        private String electoralAuthorityId;

        private EncryptionParameters parameters;

        private int length;

        /**
         * Builds a new {@link MixingKeysSpec} instance.
         * 
         * @return a new instance.
         */
        public MixingKeysSpec build() {
            requireNonNull(electionEventId, "Election event id is null.");
            requireNonNull(electoralAuthorityId,
                "Electoral authority id is null.");
            requireNonNull(parameters, "Paraeters are null.");
            if (length < 0) {
                throw new IllegalArgumentException("Length is negative.");
            }
            return new MixingKeysSpec(electionEventId,
                electoralAuthorityId, parameters, length);
        }

        /**
         * 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 electoral authority identifier.
         * 
         * @param electoralAuthorityId
         *            the electoral authority identifier
         * @return this instance.
         */
        public Builder setElectoralAuthorityId(
                String electoralAuthorityId) {
            this.electoralAuthorityId = electoralAuthorityId;
            return this;
        }

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

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