/*
 * 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.model.rule;

import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.Logger;

import com.scytl.cryptolib.api.asymmetric.AsymmetricServiceAPI;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.products.ov.commons.beans.domain.model.vote.Vote;
import com.scytl.products.ov.commons.beans.validation.ValidationErrorType;
import com.scytl.products.ov.commons.crypto.InputDataFormatterService;
import com.scytl.products.ov.commons.validation.ValidationError;
import com.scytl.products.ov.ei.services.domain.service.certificate.X509CertificateService;

/**
 * Test class for the verification of signature within the vote
 */
@RunWith(MockitoJUnitRunner.class)
public class VerifySignatureRuleTest {

    @InjectMocks
    public VerifySignatureRule rule = new VerifySignatureRule();

    @Mock
    private Logger LOG;

    @Mock
    AsymmetricServiceAPI asymmetricServiceAPI;

    @Mock
    InputDataFormatterService inputDataFormatter;

    @Mock
    X509CertificateService certificateFactory;

    @Rule
    public ExpectedException expected = ExpectedException.none();

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this.getClass());
    }

    @Test
    public void test() throws GeneralCryptoLibException, CertificateException {
        Vote vote = new Vote();
        vote.setTenantId("100");
        vote.setElectionEventId("f86b9967f5f14a01b9f70c6277c38329");
        vote.setVotingCardId("14d96e761e571a08769dc4337a2ce98b");
        vote.setBallotBoxId("b972e500fe554ed7b24e54814e9b3c85");
        vote.setBallotId("0edd4256df7d4b17a148f218080abea9");
        vote.setCredentialId("0edc375a02584cb09f35a9b956bc768f");
        String authTokenString = "token";
        vote.setSignature(Base64.getEncoder().encodeToString("signature".getBytes(StandardCharsets.UTF_8)));
        vote.setCertificate("certificate");

        vote.setAuthenticationToken(authTokenString);
        final String[] fieldsAsStringArray = vote.getFieldsAsStringArray();
        doReturn(true).when(asymmetricServiceAPI).verifySignature(any(), any(), any(byte[].class));
        doReturn(mock(X509Certificate.class)).when(certificateFactory).generateCertificate(any());
        ValidationError result = rule.execute(vote);
        assertTrue(result.getValidationErrorType().equals(ValidationErrorType.SUCCESS));
        verify(inputDataFormatter).concatenate(fieldsAsStringArray);
    }
}
