/*
 * 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.sdm.config.spring.batch.writers;


import org.apache.commons.lang3.StringUtils;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.core.io.FileSystemResource;

import java.nio.file.Path;

import com.scytl.products.oscore.logging.api.domain.Level;
import com.scytl.products.oscore.logging.api.domain.LogContent;
import com.scytl.products.oscore.logging.api.writer.LoggingWriter;
import com.scytl.products.ov.config.exceptions.specific.GenerateVerificationCardCodesException;
import com.scytl.products.ov.config.logevents.ConfigGeneratorLogEvents;
import com.scytl.products.ov.datapacks.beans.CredentialDataPack;
import com.scytl.products.ov.datapacks.beans.SerializedCredentialDataPack;
import com.scytl.products.ov.sdm.config.spring.batch.GeneratedVotingCardOutput;
import com.scytl.products.ov.utils.FingerprintGenerator;
import com.scytl.products.ov.utils.KeyStoreReader;

public class CredentialDataWriter extends FlatFileItemWriter<GeneratedVotingCardOutput> {

    private LoggingWriter loggingWriter;

    private FingerprintGenerator fingerprintGenerator;

    public CredentialDataWriter(final Path path, final FingerprintGenerator fingerprintGenerator,
                                final LoggingWriter loggingWriter) {

        this.fingerprintGenerator = fingerprintGenerator;
        this.loggingWriter = loggingWriter;

        setLineAggregator(lineAggregator());
        setTransactional(false);
        setAppendAllowed(false);
        setShouldDeleteIfExists(true);
        setResource(new FileSystemResource(path.toString()));
    }

    //writing logs here doesn't feel right. it shouldn't have 'side-effects'...
    private LineAggregator<GeneratedVotingCardOutput> lineAggregator() {

        return item -> {
            final String credentialId = item.getCredentialId();
            final String votingCardSetId = item.getVotingCardSetId(); 
            final String electionEventId = item.getElectionEventId();
            final SerializedCredentialDataPack voterCredentialDataPack = item.getVoterCredentialDataPack();

            final String credentialSerializedKeyStoreB64 = voterCredentialDataPack.getSerializedKeyStore();
            if (StringUtils.isNotBlank(credentialSerializedKeyStoreB64)) {
                String ks_cid = fingerprintGenerator.generate(credentialSerializedKeyStoreB64);
                loggingWriter.log(Level.DEBUG,
                    new LogContent.LogContentBuilder()
                        .logEvent(ConfigGeneratorLogEvents.GENCREDAT_SUCCESS_KEYSTORE_GENERATED)
                        .electionEvent(electionEventId).user("adminID")
                        .objectId(votingCardSetId).additionalInfo("c_id", credentialId)
                        .additionalInfo("ks_cid", ks_cid).createLogInfo());
            } else {
                String errorMsg = "Error - the keyStore that is being written to file is invalid";
                loggingWriter.log(Level.ERROR,
                    new LogContent.LogContentBuilder()
                        .logEvent(ConfigGeneratorLogEvents.GENCREDAT_ERROR_GENERATING_KEYSTORE)
                        .objectId(votingCardSetId).electionEvent(electionEventId)
                        .user("adminID").additionalInfo("c_id", credentialId)
                        .additionalInfo("err_desc", errorMsg).createLogInfo());
                throw new GenerateVerificationCardCodesException(errorMsg);
            }

            return String.format("%s,%s", credentialId, credentialSerializedKeyStoreB64);
        };
    }
}
