/*
 * 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.proofs.bg.commitments;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;
import com.scytl.ov.mixing.commons.tools.MultiExponentiation;

/**
 * Encapsulates a public commitment.
 */
public class PublicCommitment {

    private final ZpGroupElement commitment;

    @JsonCreator
    public PublicCommitment(@JsonProperty("element") final ZpGroupElement com) {
        commitment = com;
    }

    public PublicCommitment multiply(final PublicCommitment commitment) {

        try {
            return new PublicCommitment(this.commitment.multiply(commitment.getElement()));
        } catch (GeneralCryptoLibException e) {
            throw new CryptoLibException(e);
        }
    }

    public PublicCommitment exponentiate(final Exponent expo) {

        try {
            return new PublicCommitment(commitment.exponentiate(expo));
        } catch (GeneralCryptoLibException e) {
            throw new CryptoLibException(e);
        }
    }

    public ZpGroupElement getElement() {
        return commitment;
    }

    public boolean verifyOpening(final Exponent[] exponents, final Exponent exponentR, final CommitmentParams params,
            final MultiExponentiation multiExponentiation) {
        final PublicCommitment newCommitment =
            new PrivateCommitment(exponents, exponentR, params, multiExponentiation)
                .makePublicCommitment();
        return commitment.equals(newCommitment.getElement());
    }

    public boolean verifyOpening(final Exponent exponent, final Exponent exponentR, final CommitmentParams params,
            final MultiExponentiation multiExponentiation) {
        final PublicCommitment newCommitment =
            new PrivateCommitment(exponent, exponentR, params, multiExponentiation)
                .makePublicCommitment();
        return commitment.equals(newCommitment.getElement());
    }

    public boolean isEqual(final PublicCommitment commitment) {
        return this.commitment.equals(commitment.getElement());
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("PublicCommitment [_commitment=");
        builder.append(commitment);
        builder.append("]");
        return builder.toString();
    }
}
