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

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

import com.googlecode.jcsv.reader.CSVEntryParser;
import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.elgamal.bean.CiphertextImpl;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;
import com.scytl.cryptolib.mathematical.groups.impl.ZpSubgroup;
import com.scytl.ov.mixing.commons.exceptions.InvalidInputException;

public final class ElGamalEncryptedBallotEntryParser implements CSVEntryParser<Ciphertext> {

    private static final String PATTERN = "^[0-9]*$";

    private final ZpSubgroup zpGroup;

    public ElGamalEncryptedBallotEntryParser(final ZpSubgroup zpGroup) {
        this.zpGroup = zpGroup;
    }

    /**
     * @see com.googlecode.jcsv.reader.CSVEntryParser#parseEntry(java.lang.String[])
     */
    @Override
    public Ciphertext parseEntry(final String... args) {

        try {
            validateInputs(args);

            List<ZpGroupElement> elements = new ArrayList<>();
            for (String s : args) {
                elements.add(new ZpGroupElement(new BigInteger(s), zpGroup.getP(), zpGroup.getQ()));
            }

            return new CiphertextImpl(elements.get(0), elements.subList(1, elements.size()));

        } catch (GeneralCryptoLibException e) {
            throw new CryptoLibException(e);
        }
    }

    private static void validateInputs(final String... args) {

        if ((args == null) || (args.length == 0)) {
            throw new InvalidInputException("The input must be an initialized and non-empty");
        }

        for (String num : args) {
            if (!num.matches(PATTERN)) {
                throw new InvalidInputException("The input contains non-numeric characters");
            }
        }
    }
}
