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

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

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.validation.ValidationErrorType;
import com.scytl.products.ov.commons.validation.ValidationError;
import com.scytl.products.ov.ei.services.domain.model.ballot.Ballot;
import com.scytl.products.ov.ei.services.domain.model.ballot.BallotRepository;
import com.scytl.products.ov.ei.services.domain.model.rule.VoteCorrectnessRule;

/**
 * Test class for VoteCorrectness
 */
@RunWith(MockitoJUnitRunner.class)
public class VoteCorrectnessRuleTest {

    @InjectMocks
    @Spy
    private final VoteCorrectnessRule voteCorrectnessRule = new VoteCorrectnessRule();

    @Mock
    BallotRepository ballotRepository;

    @Mock
    Ballot ballot1;

    @Mock
    Vote vote;

    @Before
    public void initTest() {
        MockitoAnnotations.initMocks(VoteCorrectnessRuleTest.class);
    }

    @Test
    public void correctnessTrue() throws URISyntaxException, IOException, ResourceNotFoundException {

        Path ballotPath = getCurrentPath(Paths.get("l_c_ballot_lc.json"));
        String ballotString = readFile(ballotPath);
        when(ballotRepository.findByTenantIdElectionEventIdBallotId(anyString(), anyString(), anyString()))
            .thenReturn(ballot1);
        when(ballot1.getJson()).thenReturn(ballotString);
        when(vote.getCorrectnessIds()).thenReturn(
            "[[\"26d0d77f147c4620b9264977feb868f7\"]]");

        ValidationError resultExpected = new ValidationError(ValidationErrorType.SUCCESS);
        assertEquals(resultExpected.getValidationErrorType(),
            voteCorrectnessRule.execute(vote).getValidationErrorType());
    }

    @Test
    public void clauseMINFailed() throws URISyntaxException, IOException, ResourceNotFoundException {
        Path ballotPath = getCurrentPath(Paths.get("l_c_ballot_lc.json"));
        String ballotString = readFile(ballotPath);
        when(ballotRepository.findByTenantIdElectionEventIdBallotId(anyString(), anyString(), anyString()))
            .thenReturn(ballot1);
        when(ballot1.getJson()).thenReturn(ballotString);
        when(vote.getCorrectnessIds())
            .thenReturn("[[\"cf2a9da6b424478fa5e535b0174c5e26\"]]");
        ValidationError resultExpected = new ValidationError(ValidationErrorType.INVALID_VOTE_CORRECTNESS);
        assertEquals(voteCorrectnessRule.execute(vote).getValidationErrorType(),
            resultExpected.getValidationErrorType());

    }

    @Test
    public void clauseMAXFailed() throws URISyntaxException, IOException, ResourceNotFoundException {
        Path ballotPath = getCurrentPath(Paths.get("l_c_ballot_lc.json"));
        String ballotString = readFile(ballotPath);
        when(ballotRepository.findByTenantIdElectionEventIdBallotId(anyString(), anyString(), anyString()))
            .thenReturn(ballot1);
        when(ballot1.getJson()).thenReturn(ballotString);
        when(vote.getCorrectnessIds()).thenReturn(
            "[[\"26d0d77f147c4620b9264977feb868f7\",\"26d0d77f147c4620b9264977feb868f7\"],[\"26d0d77f147c4620b9264977feb868f7\"]]");
        ValidationError resultExpected = new ValidationError(ValidationErrorType.INVALID_VOTE_CORRECTNESS);
        assertEquals(voteCorrectnessRule.execute(vote).getValidationErrorType(),
            resultExpected.getValidationErrorType());

    }

    private Path getCurrentPath(final Path path) throws URISyntaxException {

        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL resource = classLoader.getResource(path.toString());
        return Paths.get(resource.toURI());

    }

    private String readFile(final Path path) throws IOException {
        return new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
    }

}
