/*
 * 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.config.model.authentication.service;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opencsv.CSVReader;
import com.scytl.products.ov.config.exceptions.ConfigurationEngineException;
import com.scytl.products.ov.config.exceptions.SequentialProvidedChallengeSourceException;
import com.scytl.products.ov.config.model.authentication.ProvidedChallenges;

public class SequentialProvidedChallengeSource implements ProvidedChallengeSource {

    private static final int PROVIDED_CHALLENGE_FILE_ALIAS_INDEX = 0;

    private static final Logger LOG = LoggerFactory.getLogger("std");

    private CSVReader providedChallengeCSVReader;

    public SequentialProvidedChallengeSource(final Path providedChallengePath) {
    	FileReader fReader = null;
    	try {
        	fReader = new FileReader(providedChallengePath.toString());
            providedChallengeCSVReader = new CSVReader(fReader, ';');
        } catch (FileNotFoundException e) {			
			LOG.error("Could not find provided challenge input data file: " + providedChallengePath.toString());
			throw new SequentialProvidedChallengeSourceException(
					"Could not find provided challenge input data file: " + providedChallengePath.toString(), e);
        }
    }

    @Override
    public ProvidedChallenges next() {

        String alias;
        List<String> challenges;
        String[] nextLine;

        try {
            synchronized (providedChallengeCSVReader) {
                nextLine = providedChallengeCSVReader.readNext();
            }

            if ((nextLine) != null) {
                alias = nextLine[PROVIDED_CHALLENGE_FILE_ALIAS_INDEX];
                challenges = Arrays
                    .asList(Arrays.copyOfRange(nextLine, PROVIDED_CHALLENGE_FILE_ALIAS_INDEX + 1, nextLine.length));
            } else {
                closeReaders();
                return null;
            }
        } catch (IOException e) {
            throw new ConfigurationEngineException("Error retrieveing the next challenge", e);
        }

        return new ProvidedChallenges(alias, challenges);
    }

    private void closeReaders() {
        try {
            providedChallengeCSVReader.close();
        } catch (IOException e) {
            LOG.error("Error trying to close file reader.");
            throw new SequentialProvidedChallengeSourceException("Error trying to close file reader.", e);
        }
    }
}
