/*
 * 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.beans.domain.model.vote;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Encrypted vote created from a string representation.
 */
public class StringEncryptedVote extends SerializableEncryptedVote {

    private static final long serialVersionUID = 3622103125746798126L;

    private static final String NO_VOTE_ERROR_MESSAGE = "There is no vote representation";

    private final BigInteger gamma;

    private final List<BigInteger> phis;

    /**
     * Create an encrypted vote from a semicolon-separated set of numbers.
     *
     * @param representation
     *            a semicolon-separated set of numbers
     */
    public StringEncryptedVote(String representation) {
        Objects.requireNonNull(representation, NO_VOTE_ERROR_MESSAGE);
        if (representation.isEmpty()) {
            throw new IllegalArgumentException(NO_VOTE_ERROR_MESSAGE);
        }

        String[] elements = representation.split(DELIMITER);

        int size = elements.length;
        if (size < 2) {
            throw new IllegalArgumentException("An encrypted vote must have at least two elements");
        }

        gamma = new BigInteger(elements[0]);

        phis = new ArrayList<>(size - 1);
        for (int i = 1; i < size; i++) {
            phis.add(new BigInteger(elements[i]));
        }
    }

    /**
     * Create an encrypted vote from its json representation.
     * 
     * @param gamma
     *            the encrypted vote gamma
     * @param phis
     *            the encrypted vote phis
     */
    @JsonCreator
    public StringEncryptedVote(@JsonProperty("gamma") BigInteger gamma, @JsonProperty("phis") List<BigInteger> phis) {
        this.gamma = Objects.requireNonNull(gamma);
        this.phis = Objects.requireNonNull(phis);
    }

    @Override
    public BigInteger getGamma() {
        return gamma;
    }

    @Override
    public List<BigInteger> getPhis() {
        return phis;
    }

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((gamma == null) ? 0 : gamma.hashCode());
		result = prime * result + ((phis == null) ? 0 : phis.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		StringEncryptedVote other = (StringEncryptedVote) obj;
		if (gamma == null) {
			if (other.gamma != null)
				return false;
		} else if (!gamma.equals(other.gamma))
			return false;
		if (phis == null) {
			if (other.phis != null)
				return false;
		} else if (!phis.equals(other.phis))
			return false;
		return true;
	}
    
}
