/*
 * 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.sdm.domain.config;

import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.web.client.RestTemplate;

import com.scytl.cryptolib.api.asymmetric.AsymmetricServiceAPI;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.asymmetric.service.AsymmetricService;
import com.scytl.products.oscore.logging.api.domain.TransactionInfo;
import com.scytl.products.oscore.logging.api.factory.LoggingFactory;
import com.scytl.products.oscore.logging.core.factory.LoggingFactoryLog4j;
import com.scytl.products.oscore.logging.core.formatter.SplunkFormatter;
import com.scytl.products.oscore.logging.core.provider.TransactionInfoProvider;
import com.scytl.products.ov.commons.path.PathResolver;
import com.scytl.products.ov.commons.path.PrefixPathResolver;
import com.scytl.products.ov.commons.sign.MetadataFileSigner;
import com.scytl.products.ov.commons.verify.MetadataFileVerifier;
import com.scytl.products.ov.sdm.application.service.BallotBoxService;
import com.scytl.products.ov.sdm.application.service.ElectionEventService;
import com.scytl.products.ov.sdm.application.service.VotingCardSetService;
import com.scytl.products.ov.sdm.domain.service.BallotBoxDataGeneratorService;
import com.scytl.products.ov.sdm.domain.service.BallotDataGeneratorService;
import com.scytl.products.ov.sdm.domain.service.ElectionEventDataGeneratorService;
import com.scytl.products.ov.sdm.domain.service.VotingCardSetDataGeneratorService;
import com.scytl.products.ov.sdm.domain.service.utils.PublicKeyLoader;
import com.scytl.products.ov.sdm.domain.service.utils.SystemTenantPublicKeyLoader;

/**
 * MVC Configuration
 */
@Configuration
@ComponentScan(basePackages = {"com.scytl.products.ov.sdm.infrastructure" })
@PropertySources({@PropertySource("classpath:config/sdm_db_test_application.properties"),
        @PropertySource("${upload.config.source}"), @PropertySource("${download.config.source}"),
        @PropertySource("${sdm.config.source}"), @PropertySource("${adapter.properties}") })
@Profile("test")
public class SdmDatabaseConfigTest {

    @Value("${user.home}")
    private String prefix;

    public SdmDatabaseConfigTest() {
        Security.addProvider(new BouncyCastleProvider());
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public PathResolver getPrefixPathResolver() {
        return new PrefixPathResolver(prefix);
    }

    @Bean
    public SystemTenantPublicKeyLoader getSystemTenantPublicKeyLoader() {
        return new SystemTenantPublicKeyLoader();
    }

    @Bean
    public PublicKeyLoader getPublicKeyLoader() {
        return new PublicKeyLoader();
    }

    @Bean
    public ElectionEventService getElectionEventService() {
        return new ElectionEventService();
    }

    @Bean
    public BallotBoxService getBallotBoxService() {
        return new BallotBoxService();
    }

    @Bean
    public VotingCardSetService getVotingCardSetService() {
        return new VotingCardSetService();
    }

    @Bean
    public BallotBoxDataGeneratorService getBallotBoxDataGeneratorService() {
        return Mockito.mock(BallotBoxDataGeneratorService.class);
    }

    @Bean
    public BallotDataGeneratorService getBallotDataGeneratorService() {
        return Mockito.mock(BallotDataGeneratorService.class);
    }

    @Bean
    public ElectionEventDataGeneratorService getElectionEventDataGeneratorService() {
        return Mockito.mock(ElectionEventDataGeneratorService.class);
    }

    @Bean
    public VotingCardSetDataGeneratorService getVotingCardSetDataGeneratorService() {
        return Mockito.mock(VotingCardSetDataGeneratorService.class);
    }

    @Bean
    public RestTemplate getRestTemplate() {
        return Mockito.mock(RestTemplate.class);
    }

    @Bean
    public MetadataFileVerifier getMetadataFileVerifier(AsymmetricServiceAPI asymmetricServiceAPI) {
        return new MetadataFileVerifier(asymmetricServiceAPI);
    }

    @Bean
    public MetadataFileSigner getMetadataFileSigner(AsymmetricServiceAPI asymmetricServiceAPI) {
        return new MetadataFileSigner(asymmetricServiceAPI);
    }

    @Bean
    AsymmetricServiceAPI asymmetricServiceAPI() throws GeneralCryptoLibException {
        return new AsymmetricService();
    }

    @Bean
    LoggingFactory loggingFactory() {
        return new LoggingFactoryLog4j(new SplunkFormatter("OV", "SDM", getTransactionInfoProvider()));
    }

    @Bean
    TransactionInfoProvider getTransactionInfoProvider() {
        TransactionInfoProvider provider = new TransactionInfoProvider();
        TransactionInfoProvider spy = Mockito.spy(provider);
        Mockito.when(spy.get()).thenReturn(new TransactionInfo(-1L, "", "", ""));
        return spy;
    }
}
