/* ===============================================================================
 *
 * Part of the InfoGlue Content Management Platform (www.infoglue.org)
 *
 * ===============================================================================
 *
 *  Copyright (C)
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2, as published by the
 * Free Software Foundation. See the file LICENSE.html for more information.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
 * Place, Suite 330 / Boston, MA 02111-1307 / USA.
 *
 * ===============================================================================
 */

package org.infoglue.cmsinstaller;

import java.io.*;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * This is the main class for the installer. What the installer should do is as follows:
 * 
 * 1. Ask for the root-access to the database we should use and set up a new database.
 * 2. All tables and access rights should be set upp by the installer as well as a small example site.
 * 3. Unpack the webarchive into the correct forlder and set up the property-files as the user specifies them. 
 */


public class InfoGlueCommandLineInstaller
{
    DatabaseCommander commander = null;
	
	//Variables
	private static String database           		= "MySQL"; 
	private static String databaseName       		= "infoglue"; 
	private static String databaseSuffix     		= ""; 
	private static String databaseServer     		= "localhost"; 
	private static String databasePort     			= "3306"; 
	private static String databaseInstance     		= ""; 
	private static String createDatabase     		= "No"; 
	private static String createInitialData    		= "No"; 
	private static String createExamples			= "Yes";
	private static String databaseUser       		= "root"; 
	private static String databasePassword   		= ""; 
	private static String infoglueDatabaseUserName  = "";
	private static String infoglueDatabasePassword	= "";
	private static String upgradeDatabaseEncoding   = "";

	private static String hostName       			= "localhost";
	private static String portNumber				= "8080";
	private static String applicationSuffix			= "";
	private static String smtpHostName				= "your.emailserver.com";
	
	private static String applicationServer       	= "Tomcat 5.x";
	private static String tomcatHomePath			= "C:\\Program\\Apache Software Foundation\\Tomcat 5.5";
	private static String tomcatHomePath2			= "C:\\Program\\Apache Software Foundation\\Tomcat 5.0";
	private static String tomcatHomePathLinux		= "/usr/local/tomcat5";
	//private static String tomcatVersion				= "5";
	//private static String tomcatHomePathLinux		= "/usr/local/tomcat4";
	private static String installCMS				= "Yes";
	private static String installWorkingDeliver		= "Yes";
	private static String installPreviewDeliver		= "No";
	private static String installLiveDeliver		= "No";
	private static String applicationPath			= "";
	
	private static String superUserName				= "root";
	private static String superUserPassword			= ServerDialog.generatePassword(6);
	
	private static String enablePortal				= "true";
	private static String actionDispatcher			= "org.infoglue.deliver.portal.dispatcher.PortalServletDispatcher";
	    
	//Introduction dialog
	private final static String introductionHeader  = "Welcome to the installation of InfoGlue CMS";
	private final static String introductionMessage = "This wizard will take you though the \ndifferent steps of setting up the cms to \nwork on your server.\n\nThis version of InfoGlue requires Java 5 (1.5.x or similar). \nYour Java-version: " + System.getProperty("java.version") + "\n\nPress enter to continue if you think you have the right version.";

	//Database dialog
	private final static String dbIntroductionHeader  = "Database setup";
	private final static String dbIntroductionMessage = "For the system to work you will have to state which database you wish to use.\n\nPlease supply the information needed below.";
	
	private final static String databaseLabel           = "Database type (Valid are \"MySQL\", \"Oracle\", \"SQL Server\" and \"DB2\"): [" + database + "] "; 
	private final static String databaseNameLabel       = "Database name: [" + databaseName + "] "; 
	private final static String databaseSuffixLabel     = "Database suffix: [" + databaseSuffix + "] "; 
	//private final static String databaseDriverNameLabel = "Database driver name: [" + databaseDriverName + "] "; 
	private final static String databaseServerLabel     = "Database server: [" + databaseServer + "] "; 
	private final static String databasePortLabel     	= "Database port: [" + databasePort + "] "; 
	private final static String databaseInstanceLabel  	= "Database instance: [] "; 
	//private final static String createDatabaseLabel 	  = "Do you want to us to create a new InfoGlue instance in the \ngiven database? If yes, supply the information needed \nbelow so we can access the database as a priviliged user.\n [no]";
	private final static String createDatabaseIntroLabel  = "The installer can automatically create a database and set up some basic data \nto make the basic functionality and examples work. \nIf you would like the installer to do these tasks you mark the options you \nwant below and then supply the installer with an administrative db-account. \nThe account must have rights to create databases and tables on \nthe server stated above.\n";
	private final static String createDatabaseLabel 	  = "Do you want the database to create a new database for infoglue automatically.\n";
	private final static String createInitialDataLabel 	  = "Do you want the installer to set up tables and initial data?. \n[no]";
	private final static String createExamplesLabel 	  = "Do you want the installer to set up the included examples?. \n[yes]";
	private final static String databaseUserLabel       = "User name (Must have administrative priviliges in the database): [" + databaseUser + "] "; 
	private final static String databasePasswordLabel   = "User password: [" + databasePassword + "] "; 
	private final static String infoglueDatabaseUserNameLabel = "InfoGlue database user: [" + infoglueDatabaseUserName + "] "; 
	private final static String infoglueDatabasePasswordLabel = "InfoGlue database password: [" + infoglueDatabasePassword + "] "; 
	private final static String upgradeDatabaseEncodingIntroductionText = "Do you want the installer to upgrade the database content to Unicode(utf-8)?";

	//Server dialog
	private final static String serverIntroductionHeader  = "Server setup";
	private final static String serverIntroductionMessage = "For the system to work we also have \nto set up the properties below so they \ncorresponds to your configuration.\n\n Please supply the information needed below.";
	
	private final static String applicationServerLabel	= "Application server (Valid are \"Tomcat 5.x\", \"Tomcat 6.x\", \"Tomcat 4.x\" and \"JBoss 4.0\"): [" + applicationServer + "]: ";
	private final static String hostNameLabel	  		= "Host Name: [" + hostName + "]: ";
	private final static String portNumberLabel	  		= "HTTP Port: [" + portNumber + "]: ";
	private final static String applicationSuffixLabel	= "Application suffix (used in shared environments): [" + applicationSuffix + "] ";
	//private final static String digitalAssetPathLabel	= "Digital asset path: [" + database + "]: ";
	private final static String smtpHostNameLabel		= "SMTP Host: [" + smtpHostName + "]: ";
	//private final static String tomcatVersionLabel		= "Tomcat version: [" + tomcatVersion + "] (4 or 5): ";
	private final static String enablePortalLabel		= "Activate JSR 168 support: [" + enablePortal + "]: ";
	private final static String applicationServerHomePathLabel = "Application server HOME: [" + tomcatHomePath + "]"; 
	private final static String installCMSLabel 		= "Install CMS Administrative tools: [" + installCMS + "] ";
	private final static String installWorkingDeliverLabel 	= "Install working deliver: [" + installWorkingDeliver + "] ";
	private final static String installPreviewDeliverLabel 	= "Install preview deliver (For complete setups): [" + installPreviewDeliver + "] ";
	private final static String installLiveDeliverLabel 	= "Install live deliver (For complete setups): [" + installLiveDeliver + "] ";
	private final static String applicationPathLabel		= "Applications directory: [" + tomcatHomePath + File.separator + "webapps" + "]";
	private final static String superUserNameLabel		= "Super user name(unlimited access to cms): [" + superUserName + "]: ";
	private final static String superUserPasswordLabel	= "Super user password: [" + superUserPassword + "]: ";
	
	//Finish dialog
	private final static String finishIntroductionHeader  = "Complete Installation";
	private final static String finishIntroductionMessage = "It's now time to complete the installation \nby copying the codebase to the webcontainer.\n\n Please press enter to complete the installation.";

	//Done dialog
	private final static String doneIntroductionHeader  = "Installation of InfoGlue CMS completed";
	private final static String doneIntroductionMessage = "InfoGlue CMS was installed successfully. \nYou can now start the tomcat server and launch \nyour favourite browser with the location \nhttp://localhost:8080/infoglueCMS/ViewCMSTool.action. \n\n.";

	
	public static void main(String[] args) throws Exception
	{
		if(args.length > 0 && args[0].equalsIgnoreCase("silent"))
		{
			InfoGlueCommandLineInstaller infoGlueInstaller = new InfoGlueCommandLineInstaller();
			if(args.length > 1)
			{
			    System.out.println("file:" + args[1]);
			    infoGlueInstaller.initSilentMode(args[1]);
			}
			else
			{
			    System.out.println("no file as argument");
			    infoGlueInstaller.initSilentMode("installconf.xml");
			}
			
			infoGlueInstaller.checkDatabase();
			infoGlueInstaller.finishInstallation();
		}
		else
		{
			InfoGlueCommandLineInstaller infoGlueInstaller = new InfoGlueCommandLineInstaller();
			infoGlueInstaller.showIntroductionDialog();
			infoGlueInstaller.showDatabaseDialog();
			infoGlueInstaller.showServerDialog();
			infoGlueInstaller.showFinishDialog();
			infoGlueInstaller.showDoneDialog();
		}
	}
		
	private void initSilentMode(String fileName) throws Exception
	{
		File file = new File(fileName);
		SAXReader xmlReader = new SAXReader();
		Document document = xmlReader.read(file);
		
		Element root = document.getRootElement();
		System.out.println("root:" + root.getName());
			
		List children = root.elements();
		System.out.println("children:" + children.size());
		
		Iterator i = children.iterator();
		while(i.hasNext())
		{
			Element child = (Element)i.next();
			String name = child.attributeValue("name");
			String value = child.attributeValue("value");
			System.out.println("name:" + name);
			System.out.println("value:" + value);
			
			if(name.equalsIgnoreCase("database"))
				database = value;
			if(name.equalsIgnoreCase("databaseName"))
				databaseName = value;
			if(name.equalsIgnoreCase("databaseSuffix"))
				databaseSuffix = value;
			if(name.equalsIgnoreCase("databaseServer"))
				databaseServer = value;
			if(name.equalsIgnoreCase("databasePort"))
				databasePort = value;
			if(name.equalsIgnoreCase("databaseInstance"))
				databaseInstance = value;
			if(name.equalsIgnoreCase("createDatabase"))
				createDatabase = value;
			if(name.equalsIgnoreCase("createInitialData"))
				createInitialData = value;
			if(name.equalsIgnoreCase("createExamples"))
				createExamples = value;
			if(name.equalsIgnoreCase("databaseUser"))
				databaseUser = value;
			if(name.equalsIgnoreCase("databasePassword"))
				databasePassword = value;
			if(name.equalsIgnoreCase("infoglueDatabaseUserName"))
				infoglueDatabaseUserName = value;
			if(name.equalsIgnoreCase("infoglueDatabasePassword"))
				infoglueDatabasePassword = value;
			if(name.equalsIgnoreCase("upgradeDatabaseEncoding"))
				upgradeDatabaseEncoding = value;
			if(name.equalsIgnoreCase("applicationServer"))
				applicationServer = value;
			if(name.equalsIgnoreCase("hostName"))
				hostName = value;
			if(name.equalsIgnoreCase("portNumber"))
				portNumber = value;
			if(name.equalsIgnoreCase("applicationSuffix"))
				applicationSuffix = value;
			if(name.equalsIgnoreCase("smtpHostName"))
				smtpHostName = value;
			if(name.equalsIgnoreCase("tomcatHomePath") || name.equalsIgnoreCase("applicationServerHomePath"))
				tomcatHomePath = value;
			//if(name.equalsIgnoreCase("tomcatVersion"))
			//	tomcatVersion = value;
			if(name.equalsIgnoreCase("installCMS"))
				installCMS = value;
			if(name.equalsIgnoreCase("installWorkingDeliver"))
				installWorkingDeliver = value;
			if(name.equalsIgnoreCase("installPreviewDeliver"))
				installPreviewDeliver = value;
			if(name.equalsIgnoreCase("installLiveDeliver"))
				installLiveDeliver = value;
			if(name.equalsIgnoreCase("applicationPath"))
				applicationPath = value;
			if(name.equalsIgnoreCase("enablePortal"))
			{
			    enablePortal = value;
			    actionDispatcher = getServletDispatcher(enablePortal);
			}
			if(name.equalsIgnoreCase("superUserName"))
			    superUserName = value;
			if(name.equalsIgnoreCase("superUserPassword"))
			    superUserPassword = value;
		}	
	}

		
	public InfoGlueCommandLineInstaller()
	{	
	}


	public static String getTomcatHomePath()
	{
		File directory = new File(tomcatHomePath);
		File directory2 = new File(tomcatHomePath2);
		//Logger.logInfo("directory:" + directory.getAbsolutePath() + ":" + directory.exists());
		if(directory.exists())
		{
			return tomcatHomePath;
		}
		else if(directory2.exists())
		{
			return tomcatHomePath2;
		}
		else
		{
			directory = new File(tomcatHomePathLinux);
			//Logger.logInfo("directory:" + directory.getAbsolutePath() + ":" + directory.exists());
			if(directory.exists())
			{
				return tomcatHomePathLinux;
			}
			else
			{
				String catalinaHome = "" + System.getProperty("CATALINA_HOME");
				directory = new File(catalinaHome);
				//Logger.logInfo("directory:" + directory.getAbsolutePath() + ":" + directory.exists());
				if(directory.exists())
				{
					return tomcatHomePathLinux;
				}
				else
				{
					catalinaHome = "" + System.getProperty("catalina.home");
					directory = new File(catalinaHome);
					//Logger.logInfo("directory:" + directory.getAbsolutePath() + ":" + directory.exists());
					if(directory.exists())
					{
						return catalinaHome;
					}
					else
					{
						return "";
					}
				}
			}
		}
		
	}

	/**
	 * This method gets the path where to store the context files.
	 */

	public static String getTomcatContextPath()
	{
		String tomcatContextPath = "webapps";
		
		if(applicationServer.startsWith("Tomcat 5") || applicationServer.startsWith("Tomcat 6"))
			tomcatContextPath = "conf" + File.separator + "Catalina" + File.separator + "localhost";
		
		return tomcatContextPath;		
	}


	public void checkDatabase() throws Exception
	{			
		if(database.equalsIgnoreCase("MySQL"))
		{
			String url = "jdbc:mysql://" + databaseServer + ":" + databasePort + "/mysql";
			commander = new MySQLDatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}
		else if(database.equalsIgnoreCase("SQL Server"))
		{
			//String url = "jdbc:microsoft:sqlserver://" + databaseServer + ":1433";
			String url = "jdbc:jtds:sqlserver://" + databaseServer + ":" + databasePort + ((databaseInstance.equalsIgnoreCase("")) ? "" : ";INSTANCE=" + databaseInstance);
			commander = new SQLServerDatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}
		else if(database.equalsIgnoreCase("Oracle"))
		{
			String url = "jdbc:oracle:thin:@" + databaseServer + ":" + databasePort + ":" + databaseName + databaseSuffix;
			commander = new OracleDatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}
		else if(database.equalsIgnoreCase("DB2"))
		{
			String url = "jdbc:db2://" + databaseServer + ":" + databasePort + "/" + databaseName + databaseSuffix;
			commander = new DB2DatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}
		else
		{
			Logger.logInfo("Database supplied:" + database);
			throw new Exception("Only 'MySQL', 'SQL Server' and 'Oracle' are supported at this moment.");
		}
		
		System.out.println("createDatabase:" + createDatabase);
		if(createDatabase.equalsIgnoreCase("yes"))
		{
			commander.testSetupDummyDatabase();
		}
		else
		{
			commander.testConnectDatabase();
		}		
	}


	public void showIntroductionDialog()
	{
		Logger.logInfo("");
		Logger.logInfo("***********************************************");
		Logger.logInfo("* "         + introductionHeader          + " *");
		Logger.logInfo("***********************************************");
		Logger.logInfo("");
	 	Logger.logInfo(introductionMessage);
		try
		{
			getInputWithDefault("");			
		}
		catch(Exception e)
		{
			Logger.logInfo("An exception occurred:" + e.getMessage());
			showIntroductionDialog();
		}
	}


	public void showDatabaseDialog()
	{

		Logger.logInfo("");
		Logger.logInfo(dbIntroductionHeader);
		Logger.logInfo("");
		Logger.logInfo(dbIntroductionMessage);
		Logger.logInfo("");
		try
		{
		 	database = getInputWithDefault(databaseLabel, new String[] {"MySQL", "SQL Server", "Oracle", "DB2"}, database, true);			
		 	System.out.print(databaseNameLabel);
			databaseName = getInputWithDefault(databaseName);
			
			if(database.equalsIgnoreCase("MySQL"))
				databasePort = "3306";
    		else if(database.equalsIgnoreCase("SQL Server"))
    			databasePort = "1433";
    		else if(database.equalsIgnoreCase("Oracle"))
    			databasePort = "1521";
    		else if(database.equalsIgnoreCase("DB2"))
    			databasePort = "50000";
			
			System.out.print(databaseSuffixLabel);
			databaseSuffix = getInputWithDefault(databaseSuffix);			
			System.out.print(databaseServerLabel);
			databaseServer = getInputWithDefault(databaseServer);	
			System.out.print(databasePortLabel);
			databasePort = getInputWithDefault(databasePort);	
			infoglueDatabaseUserName = getInputWithDefault(infoglueDatabaseUserNameLabel, new String[] {}, infoglueDatabaseUserName, false);	
			infoglueDatabasePassword = getInputWithDefault(infoglueDatabasePasswordLabel, new String[] {}, infoglueDatabasePassword, false);	

			System.out.println();
			System.out.print(createDatabaseIntroLabel);
			System.out.println();
			
			if(!database.equalsIgnoreCase("Oracle") || !database.equalsIgnoreCase("DB2"))
				createDatabase = getInputWithDefault(createDatabaseLabel, new String[] {"yes", "no"}, createDatabase, true);			
			
			createInitialData = getInputWithDefault(createInitialDataLabel, new String[] {"yes", "no"}, createInitialData, true);			
			createExamples = getInputWithDefault(createExamplesLabel, new String[] {"yes", "no"}, createExamples, true);			
			
			if(createDatabase.equalsIgnoreCase("yes") || createInitialData.equalsIgnoreCase("yes"))
			{
				databaseUser = getInputWithDefault(databaseUserLabel, new String[] {}, databaseUser, false);	
				databasePassword = getInputWithDefault(databasePasswordLabel, new String[] {}, databasePassword, true);	
			}
			else
			{
				upgradeDatabaseEncoding = getInputWithDefault(upgradeDatabaseEncodingIntroductionText, new String[] {"yes", "no"}, "no", true);	
				if(getUpgradeDatabaseEncoding())
				{
					getInputWithDefault("You MUST backup your database before continuing as this can seriously affect you data.\nPress enter when done.");
				}
			}
						
			this.checkDatabase();
			
			//setupDatabaseEnvironment();		
			
		}
		catch(Exception e)
		{
			Logger.logInfo("An exception occurred:" + e.getMessage());
			showDatabaseDialog();
		}
	}


	public void showServerDialog()
	{

		Logger.logInfo("");
		Logger.logInfo(serverIntroductionHeader);
		Logger.logInfo("");
	 	Logger.logInfo(serverIntroductionMessage);
		Logger.logInfo("");

		try
		{
			applicationServer = getInputWithDefault(applicationServerLabel, new String[] {"Tomcat 4.x", "Tomcat 5.x", "Tomcat 6.x", "JBoss 4.0"}, applicationServer, true);			

			hostName = getInputWithDefault(hostNameLabel, new String[] {}, hostName, true);			
		 	portNumber = getInputWithDefault(portNumberLabel, new String[] {}, portNumber, true);

		 	applicationSuffix = getInputWithDefault(applicationSuffixLabel, new String[] {}, applicationSuffix, true);			
		 	installCMS = getInputWithDefault(installCMSLabel, new String[] {"yes", "no"}, installCMS, true);			
		 	installWorkingDeliver = getInputWithDefault(installWorkingDeliverLabel, new String[] {"yes", "no"}, installWorkingDeliver, true);			
		 	installPreviewDeliver = getInputWithDefault(installPreviewDeliverLabel, new String[] {"yes", "no"}, installPreviewDeliver, true);			
		 	installLiveDeliver = getInputWithDefault(installLiveDeliverLabel, new String[] {"yes", "no"}, installLiveDeliver, true);
		 	smtpHostName = getInputWithDefault(smtpHostNameLabel, new String[] {}, smtpHostName, false);			
		 	enablePortal = "true"; //getInputWithDefault(enablePortalLabel, new String[] {}, enablePortal, true);
		 			
		 	//tomcatVersion = getInputWithDefault(tomcatVersionLabel, new String[] {"4", "5"}, tomcatVersion, false);			
		 	tomcatHomePath  = getExistingDirectory("Application server HOME: [" + getTomcatHomePath() + "]", tomcatHomePath, "webapps");
		 	if(enablePortal.equals("false"))
		 		applicationPath = getExistingDirectory("Applications HOME: [" + tomcatHomePath + File.separator + "webapps]", tomcatHomePath + File.separator + "webapps", null);
		 	else
		 		applicationPath = tomcatHomePath + File.separator + "webapps";
		 			
			superUserName = getInputWithDefault(superUserNameLabel, new String[] {}, superUserName, false);			
			superUserPassword = getInputWithDefault(superUserPasswordLabel, new String[] {}, superUserPassword, false);			
			
			actionDispatcher = getServletDispatcher(enablePortal);
			
			//setupPropertyFiles();		
			
		}
		catch(Exception e)
		{
			Logger.logInfo("An exception occurred:" + e.getMessage());
			showServerDialog();
		}
	}

	private String getServletDispatcher(String enablePortal)
	{
	    String actionDispatcher = "webwork.dispatcher.ServletDispatcher";
		if(enablePortal.equalsIgnoreCase("true"))
		    actionDispatcher = "org.infoglue.deliver.portal.dispatcher.PortalServletDispatcher";

		return actionDispatcher;
	}

	public void showFinishDialog()
	{
		Logger.logInfo("");
		Logger.logInfo(finishIntroductionHeader);
		Logger.logInfo("");
	 	Logger.logInfo(finishIntroductionMessage);
		Logger.logInfo("");
		try
		{
		 	getInputWithDefault("");			
			
			finishInstallation();		
			
		}
		catch(Exception e)
		{
			Logger.logInfo("An exception occurred:" + e.getMessage());
			e.printStackTrace();
			showFinishDialog();
		}
	}


	public void showDoneDialog()
	{

		Logger.logInfo("");
		Logger.logInfo(doneIntroductionHeader);
		Logger.logInfo("");
		Logger.logInfo("InfoGlue CMS was installed successfully. You can now start the tomcat server and launch your favourite browser with the location http://" + hostName + ":" + portNumber + "/infoglueCMS" + applicationSuffix + "/ViewCMSTool.action.");
	 	//Logger.logInfo(doneIntroductionMessage);
		Logger.logInfo("");
		try
		{
		 	getInputWithDefault("");			
		}
		catch(Exception e)
		{
			Logger.logInfo("An exception occurred:" + e.getMessage());
			showDoneDialog();
		}
	}

	private String getExistingDirectory(String message, String directory, String neededSubDirectory) throws Exception
	{
		System.out.print(message);
		String temp = getInputWithDefault(directory);
		File homeDir = new File(temp);
		File homeDirSubDirectory = new File(temp + File.separator + neededSubDirectory);
		if(homeDir.exists() && homeDir.isDirectory() && (neededSubDirectory == null || homeDirSubDirectory.exists()))
			return temp;
		else
		{
			Logger.logInfo("The directory did not exist.");
			return getExistingDirectory(message, directory, neededSubDirectory);
		}
	}

	public String getInputWithDefault(String defaultValue) throws Exception
	{
		String value = "";
		
		// block until enter is pressed
		while (true) 
		{
	    	char c = (char)System.in.read();
	        if (c == '\r') 
	        {
	        	c = (char)System.in.read();
	            if (c == '\n') 
	            {
	               break;
	            } 
	            else 
	            {
	               continue;
	            }
	        } 
	        else if (c == '\n') 
	        {
	            break;
	        } 
	        else 
	        {
	            value += c;
	        }
		}
		
		if(value.equals(""))
			value = defaultValue;
		
		return value;
	}


	public String getInputWithDefault(String message, String[] validStrings, String defaultValue, boolean allowEmpty) throws Exception
	{
		System.out.print(message);
		
		String value = "";
		
		// block until enter is pressed
		while (true) 
		{
	    	char c = (char)System.in.read();
	        if (c == '\r') 
	        {
	        	c = (char)System.in.read();
	            if (c == '\n') 
	            {
	               break;
	            } 
	            else 
	            {
	               continue;
	            }
	        } 
	        else if (c == '\n') 
	        {
	            break;
	        } 
	        else 
	        {
	            value += c;
	        }
		}
		
		if(!allowEmpty && value.equals(""))
		{
			value = getInputWithDefault(message, validStrings, defaultValue, allowEmpty);
		}
		else
		{
			if(value.equals(""))
				value = defaultValue;
			
			boolean isValid = false;
			for(int i=0; i<validStrings.length; i++)
			{
				String validString = validStrings[i];
				if(validString.equalsIgnoreCase(value))
				{
					isValid = true;
					break;
				}
			}
			
			if(validStrings.length == 0)
				isValid = true;
			
			if(!isValid)
				value = getInputWithDefault(message, validStrings, defaultValue, allowEmpty);
		}
				
		return value;
	}


	public void setupDatabaseEnvironment() throws Exception
	{
		DatabaseCommander commander = null;
		
		String url = "";
		if(database.equals("MySQL"))
		{
			url = "jdbc:mysql://" + databaseServer + ":" + databasePort + "/mysql";
			commander = new MySQLDatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}
		else if(database.equals("SQL Server"))
		{
			//url = "jdbc:microsoft:sqlserver://" + databaseServer + ":1433";
			url = "jdbc:jtds:sqlserver://" + databaseServer + ":" + databasePort + ((databaseInstance.equalsIgnoreCase("")) ? "" : ";INSTANCE=" + databaseInstance);
			System.out.println("url 6:" + url);
			//url = "jdbc:jtds:sqlserver://" + databaseServer + ":" + databasePort + "";
			commander = new SQLServerDatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}	
		else if(database.equalsIgnoreCase("Oracle"))
		{
			url = "jdbc:oracle:thin:" + databaseServer + ":" + databasePort + ":" + databaseName + databaseSuffix;
			commander = new OracleDatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}
		else if(database.equalsIgnoreCase("DB2"))
		{
			url = "jdbc:db2://" + databaseServer + ":" + databasePort + "/" + databaseName + databaseSuffix;
			commander = new DB2DatabaseCommander(getDatabaseDriverName(database), databaseServer, databasePort, databaseInstance, url, databaseUser, databasePassword, infoglueDatabaseUserName, infoglueDatabasePassword, databaseName + databaseSuffix, databaseSuffix, hostName, getCreateDatabase(), getCreateInitialData(), getCreateExamples(), getCreateExamples(), getCreateExamples(), getCreateExamples());
		}

		commander.createCastorRootFile();
		commander.createOSPropertiesRootFile();
		
		if(createDatabase.equalsIgnoreCase("yes") || createInitialData.equalsIgnoreCase("yes"))
		{
			Logger.logInfo("Setting up database on " + url);
			commander.setupDatabase();
		}
		else
		{
			String userName 		= infoglueDatabaseUserName;
			String password 		= infoglueDatabasePassword;
			//new UpgradeManager(getUpgradeDatabaseEncoding(), "ISO-8859-1").upgradeTo1_3(commander, databaseServer, databasePort, databaseName + databaseSuffix, userName, password);
			//new UpgradeManager(getUpgradeDatabaseEncoding(), "ISO-8859-1").upgradeTo1_3_2(commander, databaseServer, databasePort, databaseName + databaseSuffix, userName, password);
			new UpgradeManager(getUpgradeDatabaseEncoding(), "ISO-8859-1").upgradeToCurrentVersion(commander, databaseServer, databasePort, databaseName + databaseSuffix, userName, password);
		}

		Logger.logInfo("Creating castor db-file");
		commander.createCastorFile();
		//commander.createOSWorkflowFile();
		commander.createOSPropertiesFile();
		Logger.logInfo("Done setting up database");
	}
	
	/**
	 * This method sets up the needed propertyfiles.
	 * @throws Exception
	 */

	public void setupPropertyFiles(InstallationCommander installationCommander) throws Exception
	{
		String url = "";
		if(database.equals("MySQL"))
		{
		    MySQLDatabaseCommander mySQLDatabaseCommander = (MySQLDatabaseCommander)commander;
		    if(mySQLDatabaseCommander.getMysqlVersion().indexOf("4.1") > -1 && mySQLDatabaseCommander.getCharset() != null)
			    url = "jdbc:mysql://" + databaseServer + ":" + databasePort + "/" + databaseName + databaseSuffix + "?autoReconnect=true";
	        else
	            url = "jdbc:mysql://" + databaseServer + ":" + databasePort + "/" + databaseName + databaseSuffix + "?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF-8";
	        
		}
		else if(database.equals("SQL Server"))
		{
			url = "jdbc:jtds:sqlserver://" + databaseServer + ":" + databasePort + ((databaseInstance.equalsIgnoreCase("")) ? ";DatabaseName=" + databaseName + databaseSuffix + ";SelectMethod=Cursor" : ";INSTANCE=" + databaseInstance + ";DatabaseName=" + databaseName + databaseSuffix + ";SelectMethod=Cursor");
			//url = "jdbc:jtds:sqlserver://" + databaseServer + ":1433;DatabaseName=" + databaseName + databaseSuffix + ";SelectMethod=Cursor";
			//url = "jdbc:microsoft:sqlserver://" + databaseServer + ":1433;DatabaseName=" + databaseName + databaseSuffix + ";SelectMethod=Cursor";
		}
		else if(database.equals("Oracle"))
			url = "jdbc:oracle:thin:@" + databaseServer + ":" + databasePort + ":" + databaseName + databaseSuffix;
		else if(database.equals("DB2"))
			url = "jdbc:db2://" + databaseServer + ":" + databasePort + "/" + databaseName + databaseSuffix;

		
		String comment = "#";
		String installPreview = installPreviewDeliver;
		if(installPreview.equalsIgnoreCase("yes"))
			comment = "";
					
		ConfigurationFileCommander commander = new ConfigurationFileCommander(hostName, tomcatHomePath, smtpHostName, portNumber, applicationSuffix, applicationPath, comment, superUserName, superUserPassword, actionDispatcher, enablePortal, getDatabaseDriverName(database), url, infoglueDatabaseUserName, infoglueDatabasePassword, getDatabaseDialectName(database), database);
		commander.createCMSPropertyFile();
		commander.createDeliverWorkingPropertyFile(installationCommander);
		commander.createDeliverPreviewPropertyFile(installationCommander);
		commander.createDeliverLivePropertyFile(installationCommander);
		commander.createCMSWebappFile();
		commander.createDeliverWebappFile();
		commander.createHibernateConfigFile();
		TomcatConfigFilesUpdater tomcatConfigFilesUpdater = new TomcatConfigFilesUpdater();
		tomcatConfigFilesUpdater.setAppDir(applicationPath + File.separator + "infoglueCMS" + applicationSuffix);
		tomcatConfigFilesUpdater.setAppName("infoglueCMS" + applicationSuffix);
		tomcatConfigFilesUpdater.setDriverName(getDatabaseDriverName(database));
		tomcatConfigFilesUpdater.setConnUrl(url);
		tomcatConfigFilesUpdater.setLogDir(tomcatHomePath + File.separator + "infoglueCMS" + applicationSuffix + File.separator + "logs");
		tomcatConfigFilesUpdater.setPath(tomcatHomePath + File.separator + "conf");
		tomcatConfigFilesUpdater.setUsrName(infoglueDatabaseUserName);
		tomcatConfigFilesUpdater.setUsrPass(infoglueDatabasePassword);
		tomcatConfigFilesUpdater.updateConfiguration();
		
		tomcatConfigFilesUpdater.updateConfiguration("infoglueDeliverWorking" + applicationSuffix, applicationPath + File.separator + "infoglueDeliverWorking" + applicationSuffix, applicationPath + File.separator + "infoglueDeliverWorking" + applicationSuffix + File.separator + "logs");
		tomcatConfigFilesUpdater.updateConfiguration("infoglueDeliverPreview" + applicationSuffix, applicationPath + File.separator + "infoglueDeliverPreview" + applicationSuffix, applicationPath + File.separator + "infoglueDeliverPreview" + applicationSuffix + File.separator + "logs");
		tomcatConfigFilesUpdater.updateConfiguration("infoglueDeliverLive" + applicationSuffix, applicationPath + File.separator + "infoglueDeliverLive" + applicationSuffix, applicationPath + File.separator + "infoglueDeliverLive" + applicationSuffix + File.separator + "logs");
	}

	public void finishInstallation() throws Exception
	{
		setupDatabaseEnvironment();

		InstallationCommander commander = InstallationCommander.getInstallationCommander(applicationServer, applicationPath, applicationSuffix, tomcatHomePath, installCMS, installWorkingDeliver, installPreviewDeliver, installLiveDeliver, getTomcatContextPath()/*, this.tomcatVersion*/);
		setupPropertyFiles(commander);

		commander.installFiles(database);
	}
	
	
	public String getDatabaseDriverName(String databaseType)
	{
		if(databaseType.equalsIgnoreCase("MySQL"))
			return "com.mysql.jdbc.Driver";
		else if(databaseType.equalsIgnoreCase("SQL Server"))
			return "net.sourceforge.jtds.jdbc.Driver";
			//return "com.microsoft.jdbc.sqlserver.SQLServerDriver";
		else if(databaseType.equalsIgnoreCase("Oracle"))
			return "oracle.jdbc.driver.OracleDriver";
		else if(databaseType.equalsIgnoreCase("DB2"))
			return "com.ibm.db2.jcc.DB2Driver";
		else         
			return "";
	}

	public String getDatabaseDialectName(String databaseType)
	{
		if(databaseType.equalsIgnoreCase("MySQL"))
			return "net.sf.hibernate.dialect.MySQLDialect";
		else if(databaseType.equalsIgnoreCase("SQL Server"))
			return "net.sf.hibernate.dialect.SQLServerDialect";
			//return "com.microsoft.jdbc.sqlserver.SQLServerDriver";
		else if(databaseType.equalsIgnoreCase("Oracle"))
			return "net.sf.hibernate.dialect.OracleDialect";
		else if(databaseType.equalsIgnoreCase("DB2"))
			return "net.sf.hibernate.dialect.DB2Dialect";
		else
			return "";
	}
	
	public boolean getUpgradeDatabaseEncoding()
	{
		if(upgradeDatabaseEncoding.equalsIgnoreCase("yes"))
			return true;
		else
			return false;
	}
	
	public boolean getCreateDatabase()
	{
		if(createDatabase.equalsIgnoreCase("yes"))
			return true;
		else
			return false;
	}

	public boolean getCreateInitialData()
	{
		if(createInitialData.equalsIgnoreCase("yes"))
			return true;
		else
			return false;
	}
	
	public boolean getCreateExamples()
	{
		if(createExamples.equalsIgnoreCase("yes"))
			return true;
		else
			return false;
	}
}