package com.eactive.eai.rms.kakao.rolling;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import com.eactive.eai.data.jpa.BaseRepositoryImpl;
import com.eactive.eai.rms.data.config.ConfigurableMultiTenantConnectionProvider;
import com.eactive.eai.rms.data.config.TenantIdentifierResolver;
import com.eactive.kakao.rolling.RollingTableInterceptor;
import com.eactive.kakao.rolling.TableSuffixResolver;
import com.eactive.kakao.rolling.impl.RollingTableInterceptorImpl;

@Profile("rolling")
@Configuration
@ComponentScan("com.eactive.kakao.rolling")
@EnableJpaRepositories(basePackages = { "com.eactive.kakao.rolling" }, repositoryBaseClass = BaseRepositoryImpl.class)
public class RollingConfiguration {

	@Bean
	public RollingTableInterceptor rollingTableInterceptor() {
		return new RollingTableInterceptorImpl();
	}

   @Bean
   public DeployTableInterceptor deployTableInterceptor() {
      return new DeployTableInterceptorImpl();
   }

   /**
    * addInterceptor order is Interceptor's priority.
    */
   @Bean
   public CompositeHibernateInterceptor compositeHibernateInterceptor(RollingTableInterceptor rollingTableInterceptor, DeployTableInterceptor deployTableInterceptor) {
      CompositeHibernateInterceptor compositeHibernateInterceptor = new CompositeHibernateInterceptorImpl();
      compositeHibernateInterceptor.addInterceptor(rollingTableInterceptor);
      compositeHibernateInterceptor.addInterceptor(deployTableInterceptor);
      return compositeHibernateInterceptor;
   }

	@Bean
	public TableSuffixResolver tableSuffixResolver() {
		return new EMSTableSuffixResolverImpl();
	}

	@Bean("entityManagerFactory")
	@Primary
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
			@Qualifier("hibernateProperties") Properties hibernateProperties,
			ConfigurableMultiTenantConnectionProvider configurableMultiTenantConnectionProvider,
			TenantIdentifierResolver tenantIdentifierResolver) {
		LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
		bean.setDataSource(dataSource);
		bean.setPackagesToScan("com.eactive.eai.data", "com.eactive.eai.rms.data", "com.eactive.kakao.rolling");
		bean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

		bean.setJpaProperties(hibernateProperties);

		Map<String, Object> settings = new HashMap<>();
		settings.put(AvailableSettings.MULTI_TENANT, "SCHEMA");
		settings.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, configurableMultiTenantConnectionProvider);
		settings.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantIdentifierResolver);

      settings.put("hibernate.ejb.interceptor", compositeHibernateInterceptor(rollingTableInterceptor(), deployTableInterceptor()));

		bean.setJpaPropertyMap(settings);

		return bean;
	}

}
