/*
 * 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.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;

import com.googlecode.jcsv.writer.CSVWriter;
import com.googlecode.jcsv.writer.internal.CSVWriterBuilder;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.ov.mixing.commons.ballots.ElGamalEncryptedBallots;
import com.scytl.ov.mixing.commons.exceptions.MixingException;

public enum ElGamalEncryptedBallotsWriter {

    CSV {
        @Override
        public byte[] write(final OutputStream outputStream, final ElGamalEncryptedBallots encryptedBallots,
                MessageDigest messageDigest) throws IOException, GeneralCryptoLibException {

            validateContents(encryptedBallots);

            byte[] hash = null;
            try (HashCalculatingWriter out = new HashCalculatingWriter(outputStream, messageDigest);

                    CSVWriter<Ciphertext> csvWriter = new CSVWriterBuilder<Ciphertext>(out)
                        .entryConverter(new ElGamalEncryptedBallotEntryConverter()).build()) {

                csvWriter.writeAll(encryptedBallots.getBallots());
                csvWriter.flush();
                hash = out.getHash();
            }
            return hash;
        }

    };

    private static void validateContents(final ElGamalEncryptedBallots encryptedBallots) {
        if (null == encryptedBallots) {
            invalidWritingCommand("Could not write requested contents to file");
        }

    }

    private static void invalidWritingCommand(final String string) {
        throw new MixingException(string);
    }

    /**
     * Write the given {@code encryptedBallots} to the given {@path}.
     *
     * @param filePath
     *            the given path. It is assumed that all the directories of the path do exist.
     * @param encryptedBallots
     *            the re-encrypted ballots to be written.
     * @return hash of the written data
     * @throws IOException
     *             when an error occurs while writing to the file.
     * @throws GeneralCryptoLibException
     */
    public abstract byte[] write(OutputStream filePath, final ElGamalEncryptedBallots encryptedBallots,
            MessageDigest messageDigest) throws IOException, GeneralCryptoLibException;
}
