/*
 * 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.vw.services.domain.service;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.security.Security;
import java.util.logging.Logger;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;

import com.scytl.products.oscore.logging.api.writer.SecureLoggingWriter;
import com.scytl.products.ov.commons.beans.domain.model.authentication.AuthenticationToken;
import com.scytl.products.ov.commons.beans.domain.model.vote.Vote;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.beans.exceptions.VoteCastCodeRepositoryException;
import com.scytl.products.ov.commons.beans.exceptions.VoteRepositoryException;
import com.scytl.products.ov.commons.dto.CastCodeAndComputeResults;
import com.scytl.products.ov.commons.dto.ComputeResults;
import com.scytl.products.ov.commons.dto.VoteAndComputeResults;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.commons.ui.ws.rs.ObjectMappers;
import com.scytl.products.ov.vw.services.domain.model.confirmation.VoteCastResult;
import com.scytl.products.ov.vw.services.domain.model.vote.VoteRepository;

@RunWith(MockitoJUnitRunner.class)
public class VoteCastCodeServiceTest {

    private final String TENANT_ID = "100";

    private final String ELECTION_EVENT_ID = "1";

    private final String VOTING_CARD_ID = "3cc7e2a0dd394fae8d9bd2ebd4fa4b95";

    private final String VERIFICATION_CARD_ID = "4dffac3879e443d3a3634929f6a2eb07";

    private final String VOTE_CAST_SIGNATURE = "test-signature";

    private final String VOTE_CAST_CODE = "919191";

    @Mock
    private VoteRepository voteRepository;

    @Mock
    private TrackIdInstance trackIdInstance;

    @Mock
    private SecureLoggingWriter secureLoggerWriter;

    @Mock
    private Logger logger;

    @InjectMocks
    private VoteCastCodeService sut;

    @BeforeClass
    public static void setup() {
        MockitoAnnotations.initMocks(VoteCastCodeServiceTest.class);
        Security.addProvider(new BouncyCastleProvider());
    }

    @Test
    public void testGenerateVoteCastResultSuccess()
            throws ResourceNotFoundException, IOException, VoteCastCodeRepositoryException, VoteRepositoryException {
        CastCodeAndComputeResults vcMsg = new CastCodeAndComputeResults();
        vcMsg.setSignature(VOTE_CAST_SIGNATURE);
        vcMsg.setVoteCastCode(VOTE_CAST_CODE);

        VoteAndComputeResults voteAndResults = new VoteAndComputeResults();
        Vote vote = new Vote();
        vote.setAuthenticationToken(ObjectMappers.toJson(new AuthenticationToken()));
        voteAndResults.setVote(vote);
        voteAndResults.setComputeResults(new ComputeResults());

        when(voteRepository.findByTenantIdElectionEventIdVotingCardId(any(), any(), any())).thenReturn(voteAndResults);
        VoteCastResult voteCast =
            sut.generateVoteCastResult(TENANT_ID, ELECTION_EVENT_ID, VOTING_CARD_ID, VERIFICATION_CARD_ID, vcMsg);

        Assert.assertEquals(ELECTION_EVENT_ID, voteCast.getElectionEventId());
        Assert.assertEquals(VERIFICATION_CARD_ID, voteCast.getVerificationCardId());
        Assert.assertEquals(VOTE_CAST_SIGNATURE, voteCast.getVoteCastMessage().getSignature());
        Assert.assertEquals(VOTE_CAST_CODE, voteCast.getVoteCastMessage().getVoteCastCode());
    }

    @Test
    public void testGenerateVoteCastNotFoundException()
            throws ResourceNotFoundException, IOException, VoteCastCodeRepositoryException, VoteRepositoryException {
        CastCodeAndComputeResults vcMsg = new CastCodeAndComputeResults();
        vcMsg.setSignature(VOTE_CAST_SIGNATURE);
        vcMsg.setVoteCastCode(VOTE_CAST_CODE);

        when(voteRepository.findByTenantIdElectionEventIdVotingCardId(any(), any(), any()))
            .thenThrow(new ResourceNotFoundException("exception"));
        VoteCastResult voteCast =
            sut.generateVoteCastResult(TENANT_ID, ELECTION_EVENT_ID, VOTING_CARD_ID, VERIFICATION_CARD_ID, vcMsg);

        Assert.assertEquals(ELECTION_EVENT_ID, voteCast.getElectionEventId());
        Assert.assertEquals(VERIFICATION_CARD_ID, voteCast.getVerificationCardId());
        Assert.assertEquals(VOTE_CAST_SIGNATURE, voteCast.getVoteCastMessage().getSignature());
        Assert.assertEquals(VOTE_CAST_CODE, voteCast.getVoteCastMessage().getVoteCastCode());
    }

}
