package eu.dnetlib.data.statsmanager;


import org.apache.log4j.Logger;
import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
import eu.dnetlib.enabling.tools.blackboard.BlackboardNotificationHandler;
import eu.dnetlib.enabling.tools.blackboard.BlackboardServerHandler;

import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

public class StatsManager {

    private Validator validator;

    private ValidationReport validationReport;

    private DataSource dataSource;
    private CacheController prodCacheController;
    private CacheController testCacheController;

    private Logger log = Logger.getLogger(this.getClass());

    public StatsManager() {

    }


    public ValidationReport validateDatabase() throws Exception {

        this.validationReport = validator.validateDatabase();


        return validationReport;
    }


    @Transactional
    public void promoteShadowSchema() throws Exception {
        Connection con = dataSource.getConnection();

        log.info("Backing up and Replacing public schema  with shadow in " + dataSource.getConnection().getMetaData().getURL() + " ...");
        con.createStatement().execute("drop schema if exists backup CASCADE ;");
        //con.createStatement().execute("alter schema public rename to backup ;");
        con.createStatement().execute("drop schema if exists public CASCADE ;");
        con.createStatement().execute("alter schema  shadow rename TO public ;");
        log.info("All ops done!");
        con.close();
    }

    public void executeCacheAction(BlackboardJob job) throws Exception {

        if (job.getAction().equals("refreshCache")) {

            executeCommand("refreshAll", job.getParameters());
        } else if (job.getAction().equals("refreshCharts")) {

            executeCommand(job.getAction(), job.getParameters());
        } else if (job.getAction().equals("refreshNums")) {

            executeCommand(job.getAction(), job.getParameters());
        } else if (job.getAction().equals("promoteShadow")) {

            executeCommand("promoteAll", job.getParameters());
            this.promoteShadowSchema();

        } else if (job.getAction().equals("promoteNums")) {

            executeCommand(job.getAction(), job.getParameters());
        } else if (job.getAction().equals("promoteCharts")) {

            executeCommand(job.getAction(), job.getParameters());
        } else if (job.getAction().equals("promoteCache")) {

            executeCommand("promoteAll", job.getParameters());
        } else if (job.getAction().equals("restore")) {

            executeCommand(job.getAction(), job.getParameters());
        } else if (job.getAction().equals("migrate")) {

            executeCommand(job.getAction(), job.getParameters());
        } else if (job.getAction().equals("backup")) {

            executeCommand(job.getAction(), job.getParameters());

        } else {
            log.error("Wrong action given ");
            throw new Exception("Wrong action given ");
        }
        log.info("Done ! ");
    }

    private void executeCommand(String action, Map<String, String> parameters) throws Exception {

        String cache = parameters.get("cache");
        log.info("Executing  action " + action + " in " + cache + "...");
        if (cache == null || cache.contains("test")) {
            testCacheController.executeCommand(action, parameters);
        } else if (cache.contains("beta") || (cache.contains("production"))) {
            prodCacheController.executeCommand(action, parameters);
        } else {
            throw new Exception("Wrong cache id");
        }
    }


    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }


    public Validator getValidator() {
        return validator;
    }

    public void setValidator(Validator validator) {
        this.validator = validator;
    }

    public ValidationReport getValidationReport() {
        return validationReport;
    }

    public void setValidationReport(ValidationReport validationReport) {
        this.validationReport = validationReport;
    }

    public CacheController getProdCacheController() {
        return prodCacheController;
    }

    public void setProdCacheController(CacheController prodCacheController) {
        this.prodCacheController = prodCacheController;
    }

    public CacheController getTestCacheController() {
        return testCacheController;
    }

    public void setTestCacheController(CacheController testCacheController) {
        this.testCacheController = testCacheController;
    }
}
