/*
 * 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.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.batch.item.ExecutionContext;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import com.scytl.products.oscore.logging.api.writer.LoggingWriter;
import com.scytl.products.ov.config.model.authentication.AuthenticationDerivedElement;
import com.scytl.products.ov.config.model.authentication.ExtendedAuthInformation;
import com.scytl.products.ov.sdm.config.spring.batch.GeneratedVotingCardOutput;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class ExtendedAuthenticationWriterTest {

    @Rule
    public TemporaryFolder tempFolder = new TemporaryFolder();

    @Mock
    private LoggingWriter mockLoggingWriter;

    //this is to document what the exact format we are expecting the writer writes
    //authId, extraParam, encryptedSVK, electionEventId, salt, credentialId);
    private int expectedFormatLength = "%s,%s,%s,%s,%s,%s".split(",").length;

    @Test
    public void generateOutputFileWithCorrectDataFormat() throws Exception {

        doNothing().when(mockLoggingWriter).log(any(), any());

        Path tempPath = tempFolder.newFile().toPath();

        ExtendedAuthenticationWriter sut = new ExtendedAuthenticationWriter(tempPath);
        sut.open(new ExecutionContext(Collections.emptyMap()));

        String authId = "authId";
        String extraParam = "";
        String encryptedSVK = "encryptedSVK";
        String electionEventId = "electionEventId";
        String salt = "";
        String credentialId = "credentialId";

        List<GeneratedVotingCardOutput> items = new ArrayList<>();
        items.add(createOutput(authId, encryptedSVK, electionEventId, credentialId));
        items.add(createOutput(authId, encryptedSVK, electionEventId, credentialId));
        items.add(createOutput(authId, encryptedSVK, electionEventId, credentialId));

        sut.write(items);

        final List<String> strings = Files.readAllLines(tempPath);
        Assert.assertEquals(items.size(), strings.size());

        strings.forEach((String l) -> {
            final String[] columns = l.split(",");

            Assert.assertEquals(expectedFormatLength, columns.length);
            Assert.assertEquals(authId, columns[0]);
            Assert.assertEquals(extraParam, columns[1]);
            Assert.assertEquals(encryptedSVK, columns[2]);
            Assert.assertEquals(electionEventId, columns[3]);
            Assert.assertEquals(salt, columns[4]);
            Assert.assertEquals(credentialId, columns[5]);
        });
    }

    private GeneratedVotingCardOutput createOutput(final String authId, final String encryptedSVK, final String electionEventId,
                                                   final String credentialId) {

        ExtendedAuthInformation extendedAuthInformation = mock(ExtendedAuthInformation.class);
        AuthenticationDerivedElement authenticationDerivedElement = mock(AuthenticationDerivedElement.class);
        when(authenticationDerivedElement.getDerivedKeyInEx()).thenReturn(authId);
        when(extendedAuthInformation.getAuthenticationId()).thenReturn(authenticationDerivedElement);
        when(extendedAuthInformation.getExtendedAuthChallenge()).thenReturn(Optional.empty());
        when(extendedAuthInformation.getEncryptedSVK()).thenReturn(encryptedSVK);

        return GeneratedVotingCardOutput.success(null,null,null,null,credentialId,electionEventId,null,null,null,
            null, null,null,extendedAuthInformation);
    }

}
