/*
 * 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.cryptolib.ffc.cryptoapi;

import static java.util.Objects.requireNonNull;

import java.math.BigInteger;

/**
 * A pair of prime numbers used in Finite Field Cryptography (FFC) accompanied
 * with data requires for validation.
 * <p>
 * Instances of this class are immutable.
 */
public final class FFCPrimes {
    private final FFCPrime p;

    private final FFCPrime q;

    private final BigInteger firstSeed;

    /**
     * Constructor.
     * 
     * @param p
     *            the P
     * @param q
     *            the Q
     * @param firstSeed
     *            the first seed used to generate P and Q.
     */
    public FFCPrimes(FFCPrime p, FFCPrime q, BigInteger firstSeed) {
        this.p = requireNonNull(p, "P is null.");
        this.q = requireNonNull(q, "Q is null.");
        this.firstSeed = requireNonNull(firstSeed, "First seed is null.");
    }

    /**
     * Returns the p.
     * 
     * @return the p.
     */
    public FFCPrime p() {
        return p;
    }

    /**
     * Returns the q.
     * 
     * @return the q.
     */
    public FFCPrime q() {
        return q;
    }

    /**
     * Returns the seed.
     * 
     * @return the first seed.
     */
    public BigInteger firstSeed() {
        return firstSeed;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
            + ((firstSeed == null) ? 0 : firstSeed.hashCode());
        result = prime * result + ((p == null) ? 0 : p.hashCode());
        result = prime * result + ((q == null) ? 0 : q.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        FFCPrimes other = (FFCPrimes) obj;
        if (firstSeed == null) {
            if (other.firstSeed != null) {
                return false;
            }
        } else if (!firstSeed.equals(other.firstSeed)) {
            return false;
        }
        if (p == null) {
            if (other.p != null) {
                return false;
            }
        } else if (!p.equals(other.p)) {
            return false;
        }
        if (q == null) {
            if (other.q != null) {
                return false;
            }
        } else if (!q.equals(other.q)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "FFCPrimes [p=" + p + ", q=" + q + ", firstSeed="
            + firstSeed + "]";
    }
}
