package sk.ondrejhirjak.db;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import org.flywaydb.core.Flyway;
import sk.ondrejhirjak.conf.Configuration;
import sk.ondrejhirjak.db.dao.Dao;
import sk.ondrejhirjak.module.ServerModule;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;


public class DbContext implements ServerModule {

    private static final Logger LOGGER = Logger.getLogger(DbContext.class);

    private static final String DEFAULT_RESOURCE = "db/mybatis.xml";

    private static final String DB_SCRIPTS_PATH = "classpath:db/version/";

    private String resource;

    private Set<Dao<?>> daos = new HashSet<>();


    public DbContext(String resource) {
        this.resource = resource;
    }


    public DbContext() {
        this(DEFAULT_RESOURCE);
    }


    @Override
    public void init(Configuration configuration) {
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }

        LOGGER.info("Connecting to database url: '" + configuration.dbUrl + "' as user: '" + configuration.dbUsername + "'");

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, buildDbProperties(configuration));

        migrateDb(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), configuration);

        if (daos != null) {
            for (Dao<?> dao : daos) {
                dao.init(sqlSessionFactory);
            }
        }
    }


    @Override
    public void start() {

    }


    @Override
    public void stop() {

    }


    private Properties buildDbProperties(Configuration configuration) {
        Properties dbProperties = new Properties();

        dbProperties.setProperty("db.url", configuration.dbUrl);
        dbProperties.setProperty("db.username", configuration.dbUsername);
        dbProperties.setProperty("db.password", configuration.dbPassword);

        return dbProperties;
    }


    private void migrateDb(DataSource dataSource, Configuration configuration) {
        LOGGER.debug("dbAutoMigration: " + configuration.dbAutoMigration);

        if (configuration.dbAutoMigration) {
            Flyway flyway = new Flyway();

            flyway.setDataSource(dataSource);

            flyway.migrate();
        }
    }


    public void addDao(Dao<?> dao) {
        // TODO: fail to add daos after initialized
        daos.add(dao);
    }


    public void addDaos(Set<Dao<?>> newDaos) {
        // TODO: fail to add daos after initialized
        daos.addAll(newDaos);
    }
}

@@ -737,69 +737,23 @@
 ate 
-static final String DB_SCRIPTS_PATH = %22classpath:db/version/%22
+String resource
 ;%0A%0A 
@@ -766,32 +766,32 @@
 vate String 
-resource
+versions
 ;%0A%0A    priva
@@ -867,16 +867,33 @@
 resource
+, String versions
 ) %7B%0A    
@@ -922,16 +922,50 @@
 source;%0A
+        this.versions = versions;%0A
     %7D%0A%0A%0A
@@ -1018,16 +1018,22 @@
 RESOURCE
+, null
 );%0A    %7D
@@ -1844,25 +1844,24 @@
 d start() %7B%0A
-%0A
     %7D%0A%0A%0A    
@@ -1895,17 +1895,16 @@
 top() %7B%0A
-%0A
     %7D%0A%0A%0A
@@ -2522,24 +2522,122 @@
  Flyway();%0A%0A
+            if (versions != null) %7B%0A                flyway.setLocations(versions);%0A            %7D%0A%0A
             

Support custom DB versions location