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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.security.Security;
import java.util.Collections;
import java.util.Optional;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

import com.scytl.products.ov.config.SpringConfigTest;
import com.scytl.products.ov.config.model.authentication.service.AuthenticationKeyCryptoService;
import com.scytl.products.ov.constants.Constants;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfigTest.class, loader = AnnotationConfigContextLoader.class)
public class AuthenticationKeyCryptoServiceTest {

    public static final int EXPECTED_SECRETS = 2;

    @BeforeClass
    public static void init() {
        Security.addProvider(new BouncyCastleProvider());
    }

    @Autowired
    private AuthenticationKeyCryptoService authenticationKeyCryptoService;

    private final String eeID = "d710a4df654a4d7480df52f0ae9de610";

    private static final StartVotingKey startVotingKey = StartVotingKey.ofValue("zpfrcmn28mcct4pf682w");

    private static final AuthenticationKey authenticationKey = AuthenticationKey.ofSecrets("zpfrcmn28mcct4pf682w",
        Optional.of(Collections.singletonList("zpfrcmn28mcct4pf682w")));

    @Test
    public void deriveAuthKeyId() {

        final AuthenticationDerivedElement authId =
            authenticationKeyCryptoService.deriveElement(Constants.AUTH_ID, eeID, authenticationKey.getValue());
        assertNotNull(authId);

    }

    @Test
    public void deriveAuthKeyPassword() {

        final AuthenticationDerivedElement authenticationKeyPassword =
            authenticationKeyCryptoService.deriveElement(Constants.AUTH_PW, eeID, authenticationKey.getValue());
        assertNotNull(authenticationKeyPassword);

    }

    @Test
    public void encryptSVK() {

        final AuthenticationDerivedElement authenticationKeyPassword =
            authenticationKeyCryptoService.deriveElement(Constants.AUTH_PW, eeID, authenticationKey.getValue());
        String encryptStartVotingKey =
            authenticationKeyCryptoService.encryptSVK(startVotingKey, authenticationKeyPassword);
        assertNotNull(encryptStartVotingKey);

    }

    @Test
    public void decryptSVK() {
        final AuthenticationDerivedElement authenticationKeyPassword =
            authenticationKeyCryptoService.deriveElement(Constants.AUTH_PW, eeID, authenticationKey.getValue());
        String encryptedStartVotingKey =
            authenticationKeyCryptoService.encryptSVK(startVotingKey, authenticationKeyPassword);
        final String originalSVK =
            authenticationKeyCryptoService.decryptSVK(encryptedStartVotingKey, authenticationKeyPassword);
        assertEquals(originalSVK, startVotingKey.getValue());

    }

}
