/*
 * 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.channel.cc.mixing.service;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;

import java.io.IOException;
import java.security.KeyManagementException;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.elgamal.bean.ElGamalKeyPair;
import com.scytl.products.ov.channel.cc.commons.keymanagement.KeyManager;
import com.scytl.products.ov.channel.cc.mixing.service.WrongMixingResultsTest.Config;
import com.scytl.products.ov.channel.cc.mixing.service.conversion.ConverterException;
import com.scytl.products.ov.channel.cc.mixing.service.conversion.LocationsProviderMixingOutputConverter;
import com.scytl.products.ov.channel.cc.mixing.service.conversion.MixingOutputConverter;
import com.scytl.products.ov.commons.dto.MixingDTO;
import com.scytl.products.ov.commons.dto.mixing.MixingPayload;

/**
 * Tests {@link InternalMixDecryptServiceImpl} where the mixing, even though is
 * has not failed, returns incorrect results that will cause failures down the
 * line.
 */
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = Config.class)
public class WrongMixingResultsTest {

    @Autowired
    private ElGamalKeyPair electoralAuthorityKeyPair;

    @Value("${queues.md-mixdec.req}")
    private String queueName;

    @Autowired
    private InternalMixDecryptService sut;

    @Autowired
    private KeyManager keyManager;

    private TestUtil testUtil;

    @Before
    public void setUp() throws IOException, GeneralCryptoLibException {
        testUtil = new TestUtil(sut, queueName, keyManager, electoralAuthorityKeyPair);
    }

    @Test
    public void testIncorrectMixingOutput() throws KeyManagementException, GeneralCryptoLibException, IOException {
        MixingDTO dto = testUtil.createMixingDTO(3);
        MixingPayload initialPayload = dto.getPayload();
        testUtil.executeMixing(dto);
        assertNotNull(dto.getError());
        assertEquals(dto.getError().getErrorClass(), ConverterException.class.getName());
        assertEquals(dto.getPayload(), initialPayload);
    }

    @Configuration
    @Import(TestConfig.class)
    static class Config {
        @Bean
        MixingOutputConverter mixingOutputConverter() throws ConverterException {
            MixingOutputConverter mixingOutputConverter = spy(new LocationsProviderMixingOutputConverter());

            doThrow(new ConverterException(new IllegalStateException("Oops!"))).when(mixingOutputConverter)
                .convert(any(), any(), any());

            return mixingOutputConverter;
        }
    }
}
