package com.atlassian.bitbucket.mesh;

import com.atlassian.bitbucket.mesh.context.DataSetTestExecutionListener;
import com.atlassian.bitbucket.mesh.dbunit.DatabaseConnectionFactory;
import com.atlassian.bitbucket.mesh.test.context.MockitoTestExecutionListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.io.Resource;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;

import javax.sql.DataSource;

@Configuration
@PropertySources({
        @PropertySource("classpath:application-private.properties"),
        @PropertySource("classpath:application-public.properties"),
        @PropertySource("classpath:application-test.properties")
})
public class MeshTestWiring {

    @Bean
    public H2DatabaseValidator databaseValidator() {
        return new H2DatabaseValidator(null);
    }

    @Bean
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties("jdbc:h2:mem:mesh;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE", "sa", "");
    }

    @Bean
    public DatabaseConnectionFactory databaseConnectionFactory(DataSource dataSource) {
        return new DatabaseConnectionFactory(dataSource);
    }

    @Bean
    DataSetTestExecutionListener dataSetTestExecutionListener(DatabaseConnectionFactory connectionFactory,
                                                              @Value("classpath:dbunit/mesh-schema.dtd") Resource dtd) {
        return new DataSetTestExecutionListener(connectionFactory, dtd);
    }

    @Bean
    DependencyInjectionTestExecutionListener dependencyInjectionTestExecutionListener() {
        return new DependencyInjectionTestExecutionListener();
    }

    @Bean
    DirtiesContextTestExecutionListener dirtiesContextTestExecutionListener() {
        return new DirtiesContextTestExecutionListener();
    }

    @Bean
    public IncompatibleSidecarDatabaseResetter incompatibleDatabaseResetter() {
        return new IncompatibleSidecarDatabaseResetter(new MockEnvironment(), null);
    }

    @Bean
    MockitoTestExecutionListener mockitoTestExecutionListener() {
        return new MockitoTestExecutionListener();
    }

    @Bean
    TransactionalTestExecutionListener transactionalTestExecutionListener() {
        return new TransactionalTestExecutionListener();
    }
}
