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

import com.googlecode.jcsv.reader.CSVReader;
import com.googlecode.jcsv.reader.internal.CSVReaderBuilder;
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.SecureLoggingWriter;
import com.scytl.products.ov.tallying.commons.beans.AuditableVote;
import com.scytl.products.ov.tallying.commons.exception.TallyingException;
import com.scytl.products.ov.tallying.commons.log.TallyingLogConstants;
import com.scytl.products.ov.tallying.commons.log.TallyingLogEvents;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
 * A class in charge of reading the input CSV with auditable votes.
 */
public class AuditableVotesReader {

    private final AuditableVoteEntryParser entryParser;

    @Autowired
    private SecureLoggingWriter secureLog;

    public AuditableVotesReader(final AuditableVoteEntryParser entryParser) {
        this.entryParser = entryParser;
    }

    public List<AuditableVote> read(final Path fullPath, final String electionEventId, final String ballotBoxId) throws TallyingException {

        List<AuditableVote> auditableVotes = new ArrayList<>();
        try (Reader reader = new FileReader(fullPath.toString());
                CSVReader<AuditableVote> auditableVotesReader = new CSVReaderBuilder<AuditableVote>(
                        reader).entryParser(entryParser).build()) {

            auditableVotes.addAll(auditableVotesReader.readAll());

        } catch (IOException ex) {
            secureLog.log(Level.ERROR, new LogContent.LogContentBuilder()
                    .objectId(ballotBoxId)
                    .logEvent(TallyingLogEvents.AUDITABLE_VOTES_READING_FAILED)
                    .user("adminID")
                    .electionEvent(electionEventId)
                    .additionalInfo(TallyingLogConstants.FILE_NAME, String.valueOf(fullPath.getFileName()))
                    .additionalInfo(TallyingLogConstants.ERR_DESC, ExceptionUtils.getRootCauseMessage(ex))
                    .createLogInfo());
            throw new TallyingException(TallyingLogEvents.AUDITABLE_VOTES_READING_FAILED.getInfo(), ex);
        }

        return auditableVotes;
    }
}