/*
 * 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.interoperation.js.utils;

import java.util.List;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.interoperation.js.constants.CommonConstants;
import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;
import com.scytl.cryptolib.proofs.bean.ProofPreComputedValues;

/**
 * Utility for serializing collections of mathematical objects. Note: This
 * utility should be discarded after cryptoLib is updated to support these types
 * of serializations.
 */
public final class MathematicalCollectionSerializer {

    /**
     * Default constructor.
     */
    private MathematicalCollectionSerializer() {
    }

    /**
     * Serializes a collection of Zp group elements to JSON format.
     * 
     * @param zpGroupElements
     *            the collection of Zp group elements to serialize.
     * @return the serialized collection of Zp group elements.
     * @throws GeneralCryptoLibException
     *             if a Zp group element cannot be added to the serialization.
     */
    public static String zpGroupElementsToJson(
            final List<ZpGroupElement> zpGroupElements)
            throws GeneralCryptoLibException {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(zpGroupElements.get(0).toJson());
        for (int i = 1; i < zpGroupElements.size(); i++) {
            stringBuilder.append(
                CommonConstants.TEST_DATA_SERIALIZATION_DELIMITER);
            stringBuilder.append(zpGroupElements.get(i).toJson());
        }

        return stringBuilder.toString();
    }

    /**
     * Serializes a collection of exponents to JSON format.
     * 
     * @param exponents
     *            the collection of exponents to serialize.
     * @return the serialized collection of exponents.
     * @throws GeneralCryptoLibException
     *             if an exponent cannot be added to the serialization.
     */
    public static String exponentsToJson(final List<Exponent> exponents)
            throws GeneralCryptoLibException {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(exponents.get(0).toJson());
        for (int i = 1; i < exponents.size(); i++) {
            stringBuilder.append(
                CommonConstants.TEST_DATA_SERIALIZATION_DELIMITER);
            stringBuilder.append(exponents.get(i).toJson());
        }

        return stringBuilder.toString();
    }

    /**
     * Serializes the pre-computed values of a zero knowledge proof of knowledge
     * to JSON format.
     * 
     * @param preComputedValues
     *            the pre-computed values to serialize.
     * @return the serialized pre-computed values.
     * @throws GeneralCryptoLibException
     *             if any of the components of the pre-computed values cannot be
     *             JSON serialized.
     */
    public static String proofPreComputedValuesToJson(
            final ProofPreComputedValues preComputedValues)
            throws GeneralCryptoLibException {

        List<Exponent> exponents = preComputedValues.getExponents();
        String exponentsJson = exponentsToJson(exponents);

        List<ZpGroupElement> phiOutputs =
            preComputedValues.getPhiOutputs();
        String phiOutputsJson = zpGroupElementsToJson(phiOutputs);

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("exponents: ");
        stringBuilder.append(exponentsJson);
        stringBuilder.append(
            CommonConstants.TEST_DATA_SERIALIZATION_DELIMITER);
        stringBuilder.append("phiOutputs: ");
        stringBuilder.append(phiOutputsJson);

        return stringBuilder.toString();
    }
}
