package org.cagrid.tests.data.styles.cacore42.steps;

import gov.nih.nci.cagrid.common.StreamGobbler;
import gov.nih.nci.cagrid.common.Utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cagrid.tests.data.styles.cacore42.DatabaseProperties;
import org.cagrid.tests.data.styles.cacore42.ExampleProjectInfo;

public class SdkDatabaseStep extends AbstractDatabaseStep {
    
    private static Log LOG = LogFactory.getLog(SdkDatabaseStep.class);
    
    private DatabaseOperation operation = null;

    public SdkDatabaseStep(DatabaseOperation operation) {
        super();
        this.operation = operation;
    }
    
    
    public void runStep() {
        try {
            switch (operation) {
                case CREATE:
                    LOG.debug("CREATING caCORE SDK DATABASE");
                    getDatabase().createDatabaseIfNeeded();
                    break;
                case INSTALL:
                    LOG.debug("INSTALLING caCORE SDK DATABASE");
                    List<String> creationStatements = getExampleDatabaseCreationStatements();
                    for (String statement : creationStatements) {
                        LOG.debug("-- EXECUTING DB CREATION STATEMENT --");
                        LOG.debug(statement);
                        getDatabase().update(statement);
                    }
                    break;
                case DESTROY:
                    LOG.debug("DESTROYING caCORE SDK DATABASE");
                    getDatabase().destroyDatabase();
                    break;
            }
        } catch (Exception ex) {
            String message = "Error performing database operation " + operation.name() + ": " + ex.getMessage();
            LOG.error(message, ex);
            fail(message);
        }
    }
    
    
    private List<String> getExampleDatabaseCreationStatements() {
        List<String> statements = new LinkedList<String>();
        try {
            File[] dbScripts = ExampleProjectInfo.getMysqlDatabaseInstallFiles();
            for (File script : dbScripts) {
                LOG.debug("Executing db script " + script.getAbsolutePath());
                List<String> command = new ArrayList<String>();
                command.add(getMysqlExecutable());
                command.add("-u");
                command.add(DatabaseProperties.getUsername());
                if (DatabaseProperties.getPassword() != null && DatabaseProperties.getPassword().length() != 0) {
                    command.add("-p");
                    command.add(DatabaseProperties.getPassword());
                }
                command.add("-D");
                command.add(DatabaseProperties.getSchemaName());
                String[] cmdArray = new String[command.size()];
                cmdArray = command.toArray(cmdArray);
                // read the script
                StringBuffer sql = Utils.fileToStringBuffer(script);
                Process proc = Runtime.getRuntime().exec(cmdArray);
                // push the script into the mysql process to load the DB
                BufferedOutputStream out = new BufferedOutputStream(proc.getOutputStream());
                out.write(sql.toString().getBytes());
                new StreamGobbler(proc.getErrorStream(), StreamGobbler.TYPE_ERR, System.err).start();
                new StreamGobbler(proc.getInputStream(), StreamGobbler.TYPE_OUT, System.out).start();
                out.close();
                int code = -1;
                try {
                    code = proc.waitFor();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                    fail("Error running database script: " + ex.getMessage());
                }
                assertEquals("Unexpected exit code from mysql script", 0, code);
            }
        } catch (IOException ex) {
            String message = "Error reading database creation script: " + ex.getMessage();
            LOG.error(message, ex);
            fail(message);
        }
        return statements;
    }
    
    
    private String getMysqlExecutable() {
        StringTokenizer pathTokenizer = new StringTokenizer(System.getenv("PATH"), File.pathSeparator);
        String mysqlName = "mysql";
        boolean isWindows = System.getProperty("os.name").toLowerCase().contains("windows");
        if (isWindows) {
            mysqlName += ".exe";
        }
        while (pathTokenizer.hasMoreTokens()) {
            String path = pathTokenizer.nextToken();
            File maybeMysql = new File(path, mysqlName);
            if (maybeMysql.exists() && maybeMysql.isFile()) {
                LOG.debug("Probably found mysql on the path: " + maybeMysql.getAbsolutePath());
                return maybeMysql.getAbsolutePath();
            }
        }
        return null;
    }
    
    
    public static enum DatabaseOperation {
        CREATE, INSTALL, DESTROY
    }
}

@@ -263,38 +263,8 @@
 t;%0D%0A
-import java.util.LinkedList;%0D%0A
 impo
@@ -1252,353 +1252,25 @@
     
-List%3CString%3E creationStatements = getExampleDatabaseCreationStatements();%0D%0A                    for (String statement : creationStatements) %7B%0D%0A                        LOG.debug(%22-- EXECUTING DB CREATION STATEMENT --%22);%0D%0A                        LOG.debug(statement);%0D%0A                        getDatabase().update(statement);%0D%0A                    %7D
+createDatabase();
 %0D%0A  
@@ -1748,122 +1748,31 @@
 ate 
-List%3CString%3E getExampleDatabaseCreationStatements() %7B%0D%0A        List%3CString%3E statements = new LinkedList%3CString%3E();
+void createDatabase() %7B
 %0D%0A  
@@ -3552,24 +3552,49 @@
 abase script
+ %22 + script.getName() + %22
 : %22 + ex.get
@@ -3693,17 +3693,37 @@
 l script
-%22
+ %22 + script.getName()
 , 0, cod
@@ -3950,36 +3950,8 @@
  %7D%0D%0A
-        return statements;%0D%0A
     

fix db weirdness