package com.farm.environment.configuration;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {
        "com.farm.database"
})
@EnableAutoConfiguration
public class DatabaseConfiguration {

    private Environment environment;

    @Autowired
    public DatabaseConfiguration(Environment environment) {
        this.environment = environment;
    }

    @SuppressWarnings("ConstantConditions")
    @Bean
    @LiquibaseDataSource
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig("/database/hikari.properties");
        return new HikariDataSource(config);
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPackagesToScan(getProperty("package.to.scan.entities"));

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setJpaProperties(getHibernateProperties());

        return entityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);

        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
        return new PersistenceExceptionTranslationPostProcessor();
    }

    private String getProperty(String key) {
        return environment.getProperty(key);
    }

    private Properties getHibernateProperties() {
        Properties properties = new Properties();

        properties.setProperty("hibernate.hbm2ddl.auto", getProperty("hibernate.hbm2ddl.auto"));
        properties.setProperty("hibernate.dialect", getProperty("hibernate.dialect"));
        properties.setProperty("hibernate.show_sql", getProperty("hibernate.show_sql"));
        properties.setProperty("hibernate.generate_statistics", getProperty("hibernate.generate_statistics"));
        properties.setProperty("hibernate.connection.pool_size", getProperty("hibernate.connection.pool_size"));

        return properties;
    }
}

@@ -477,32 +477,26 @@
 k.co
-ntext.annotation.Primary
+re.env.Environment
 ;%0Aim
@@ -521,39 +521,44 @@
 mework.core.
-env.Environment
+io.ClassPathResource
 ;%0Aimport org
@@ -1686,122 +1686,1063 @@
     
-HikariConfig config = new HikariConfig(%22/database/hikari.properties%22
+String hikariPropertiesFilePath = %22/database/hikari.properties%22;%0A        ClassPathResource configFile = new ClassPathResource(hikariPropertiesFilePath);%0A        if (configFile.exists()) %7B%0A            HikariConfig config = new HikariConfig(hikariPropertiesFilePath);%0A            return new HikariDataSource(config);%0A        %7D%0A%0A        return getHikariDataSourceFromArguments(
 );%0A    
+%7D%0A%0A
     
-return new HikariDataSource(config)
+private HikariDataSource getHikariDataSourceFromArguments() %7B%0A        HikariDataSource dataSource = new HikariDataSource();%0A        String userName = getProperty(%22dataSource.user%22);%0A        String password = getProperty(%22dataSource.password%22);%0A        String dataBaseName = getProperty(%22dataSource.databaseName%22);%0A        String portNumber = getProperty(%22dataSource.portNumber%22);%0A        String serverAddress = getProperty(%22dataSource.serverName%22);%0A%0A        dataSource.setUsername(userName);%0A        dataSource.setPassword(password);%0A        dataSource.setJdbcUrl(%22jdbc:postgresql://%22 + serverAddress + %22:%22 +portNumber + %22/%22 + dataBaseName);%0A        return dataSource
 ;%0A  

add init database from arguments