/*
 * 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
 */
/**
 * $Id$
 *
 * @author riglesias
 * @date 7/11/16
 *
 *
 * All rights reserved.
 */
package com.scytl.product.ov.ea.services.domain.validation;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.cert.CertificateException;

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.runners.MockitoJUnitRunner;
import org.slf4j.Logger;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.certificates.cryptoapi.CryptoAPIX509Certificate;
import com.scytl.products.oscore.logging.api.writer.SecureLoggingWriter;
import com.scytl.products.ov.commons.beans.domain.model.authentication.AuthenticationContent;
import com.scytl.products.ov.commons.beans.domain.model.authentication.AuthenticationData;
import com.scytl.products.ov.commons.beans.domain.model.authentication.AuthenticationToken;
import com.scytl.products.ov.commons.beans.exceptions.ExtendedAuthValidationException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.crypto.InputDataFormatterService;
import com.scytl.products.ov.commons.crypto.configuration.CertificateParameters;
import com.scytl.products.ov.ea.domain.model.extendedauthentication.validation.rules.CredentialIdValidation;

@RunWith(MockitoJUnitRunner.class)
public class CertificateValidationTest extends ValidationTest {

    public static final String TENANT_ID = "1";

    public static final String ELECTION_EVENT_ID = "1";

    public static final String OTHER = "lafjdlsjfd";

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

    @InjectMocks
    CredentialIdValidation validation = new CredentialIdValidation();


    @Mock
    private AuthenticationData authenticationDataMock;

    @Mock
    private AuthenticationContent authenticationContentMock;

    @Mock
    private InputDataFormatterService inputDataFormatterServiceMock;

    @Mock
    private static Logger LOG;

    @Mock
    protected SecureLoggingWriter secureLoggingWriter;

    @Test
    public void testCertificateOK()
            throws IOException, GeneralCryptoLibException, ResourceNotFoundException,
            CertificateException {

        final AuthenticationToken token = generateToken(TENANT_ID, ELECTION_EVENT_ID);
        final AuthTokenCryptoInfo tokenKeys = getTokenKeys();
        signToken(tokenKeys.getPrivateKey(), token);
        final CertificateParameters certificateParameters =
            createCertificateParameters(token.getVoterInformation().getCredentialId());
        final KeyPair keyPairForSigning = getKeyPairForSigning();
        final CryptoAPIX509Certificate certificate = certificateGenerator.generate(certificateParameters,
            keyPairForSigning.getPublic(), keyPairForSigning.getPrivate());
        final String pemEncoded = new String(certificate.getPemEncoded(), StandardCharsets.UTF_8);
        validation.validateCertificate(pemEncoded, token);

    }

    @Test
    public void testInvalidCredentialInCertificate()
            throws IOException, GeneralCryptoLibException {
        expectedException.expect(ExtendedAuthValidationException.class);
        final AuthenticationToken token = generateToken(TENANT_ID, ELECTION_EVENT_ID);
        final AuthTokenCryptoInfo tokenKeys = getTokenKeys();
        signToken(tokenKeys.getPrivateKey(), token);
        final CertificateParameters certificateParameters =
            createCertificateParameters(token.getVoterInformation().getCredentialId());
        token.getVoterInformation().setCredentialId(OTHER);
        final KeyPair keyPairForSigning = getKeyPairForSigning();
        final CryptoAPIX509Certificate certificate = certificateGenerator.generate(certificateParameters,
            keyPairForSigning.getPublic(), keyPairForSigning.getPrivate());
        final String pemEncoded = new String(certificate.getPemEncoded(), StandardCharsets.UTF_8);
        validation.validateCertificate(pemEncoded, token);

    }

    @Test
    public void testThrowingCryptoLibException()
            throws IOException, GeneralCryptoLibException {
        expectedException.expect(ExtendedAuthValidationException.class);
        final AuthenticationToken token = generateToken(TENANT_ID, ELECTION_EVENT_ID);
        String wronCertificate = "THIS_IS_NOT_A_CERTICATE_BUT_OTHER_THING";
        validation.validateCertificate(wronCertificate, token);

    }


}
