/*
 * 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.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;

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

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Before;
import org.junit.BeforeClass;
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.springframework.beans.factory.annotation.Autowired;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.api.primitives.PrimitivesServiceAPI;
import com.scytl.cryptolib.derivation.cryptoapi.CryptoAPIDerivedKey;
import com.scytl.cryptolib.derivation.cryptoapi.CryptoAPIPBKDFDeriver;
import com.scytl.products.ov.config.model.authentication.service.ChallengeService;

@RunWith(MockitoJUnitRunner.class)
// @ContextConfiguration(classes = SpringConfigTest.class, loader =
// AnnotationConfigContextLoader.class)
public class ChallengeServiceTest {

    public static final int EXPECTED_ELEMENTS = 1;

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

    @Before
    public void beforeMethod() {
        MockitoAnnotations.initMocks(ChallengeService.class);
    }

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

    @Autowired
    @InjectMocks
    private ChallengeService challengeService;

    @Mock
    private PrimitivesServiceAPI primitivesServiceMock;

    @Mock
    private CryptoAPIPBKDFDeriver deriverMock;

    @Mock
    CryptoAPIDerivedKey cryptoApiDerivedKeyMock;

    @Mock
    private ChallengeGenerator challengeGenerator;

    private final String challenge = "d710a4df654a4d7480df52f0ae9de610";

    private final String alias = "alias";

    private final String derivedChanllengeString = "adsfkasdfklhaskldfhlskajhflkawjshdlkfjhaslkjfdh";

    private final ExtraParams extraParams = ExtraParams.ofChallenges(Optional.of(challenge), Optional.of(alias));

    @Test
    public void createChallenge() throws GeneralCryptoLibException {

        when(primitivesServiceMock.getPBKDFDeriver()).thenReturn(deriverMock);
        when(deriverMock.deriveKey(any(), any())).thenReturn(cryptoApiDerivedKeyMock);
        when(cryptoApiDerivedKeyMock.getEncoded()).thenReturn(derivedChanllengeString.getBytes());
        when(challengeGenerator.generateExtraParams()).thenReturn(extraParams);

        assertNotNull(challengeService.createExtendedAuthChallenge());

    }

    @Test
    public void createWithCryptoLibException() throws GeneralCryptoLibException {

        expectedException.expect(GeneralCryptoLibException.class);

        when(primitivesServiceMock.getPBKDFDeriver()).thenReturn(deriverMock);
        when(deriverMock.deriveKey(any(), any())).thenThrow(GeneralCryptoLibException.class);
        when(challengeGenerator.generateExtraParams()).thenReturn(extraParams);

        challengeService.createExtendedAuthChallenge();

    }

}
