package org.greenstone.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;

import org.apache.log4j.PropertyConfigurator;

import org.greenstone.server.BaseServer;
import org.greenstone.server.BaseProperty;
import org.greenstone.util.GlobalProperties;
import org.greenstone.util.ProtocolPortProperties;
import org.greenstone.util.RunAnt;

public class Server3 extends BaseServer
{
        String opt_ant_properties = null;
        ProtocolPortProperties protocolPortProps = null;

    	public Server3(String gsdl3_src_home, String lang)
	{
	    this(gsdl3_src_home, lang, "");
	}
    
    	public Server3(String gsdl3_src_home, String lang, String testingMode)
	{
		super(gsdl3_src_home,
		      lang,
		      gsdl3_src_home + File.separatorChar + "build.properties",
		      "web"+File.separator+"logs");

		setTesting(testingMode); // specify if running in automated testing mode or normal
		
		// config properties are loaded into the config_properties object
		// now test the port and protocol values are sane or exit.
		try {
		    protocolPortProps = new ProtocolPortProperties(config_properties);
		} catch(Exception e) {
		    String errorMsg = "@@@ Error with ports/protocol in " + config_properties_file + ": " + e.getMessage();

		    // print it everywhere, because port/protocol misconfiguration is a fatal error and we're exiting
		    logger_.error(errorMsg, e);
		    System.err.println(errorMsg);
		    // If error, then quit this app as soon as possible
		    System.exit(-1);
		}
		
		Property = new Server3Property(protocolPortProps.getDefaultPortPropertyName());
                
		       // defaultPortPropertyName can be 'localhost.port.http' or 'tomcat.port.https'
		       // depending on which of http and https is the first value of 'server.protocols'

		String frame_title = dictionary.get("ServerControl.Frame_Title");
		BaseServerControl.invokeInDispatchThreadIfNeeded(true, new Runnable() {
			public void run() {
			    server_control_ = new Server3Control(Server3.this, frame_title);
			}
		    });

		/** Ant command targets for managing Web server */
		START_CMD = "start";
		RESTART_CMD = "restart";
		CONFIGURE_CMD = "configure";
		STOP_CMD = "force-stop-tomcat force-stop-derby";

		String is_read_only = System.getProperty("gsdl3home.isreadonly","false");
		if (is_read_only.equals("true")) {
                  String gsdl3_writablebasedir = System.getProperty("gsdl3.writablebasedir",gsdl3_src_home);
                  opt_ant_properties = "-Dgsdl3home.isreadonly=true -Dgsdl3.writablebasedir="+gsdl3_writablebasedir;
		}
		
		autoStart();
	}

	protected int runTarget(String cmd)
	{
		RunAnt runAnt = new RunAnt(opt_ant_properties);
		runAnt.setTargetCmd(cmd);
		if(System.getenv("GSDL3SRCHOME") != null) {
		    // For automated testing of GSI, need to launch ant stop/cmds start
		    // from GSDL3SRCHOME folder.
		    runAnt.setLaunchDir(System.getenv("GSDL3SRCHOME"));
		}
		runAnt.run();
		return runAnt.getTargetState();
	}

	public String getBrowserURL()
	{
		return GlobalProperties.getFullGSDL3WebAddress() + config_properties.getProperty(BaseServer.Property.DEFAULT_SERVLET);
	}

	public String fallbackGSDL3Home() 
	{ 
		return gsdl_home + File.separator + "web"; //System.getenv("GSDL3SRCHOME") + File.separator + "web"; 
	} 

	public void reload()
	{
	        String prop_file_path = System.getProperty("gsdl3.writablebasedir",gsdl_home) + File.separator + "web"+File.separator+"WEB-INF" + File.separator+"classes"+File.separator+"global.properties";
		GlobalProperties.loadGlobalProperties(prop_file_path); // properties file may have changed, so reload it
	}

	public static void main(String[] args)
	{
		if ((args.length < 1) || (args.length > 3))
		{
			System.err.println("Usage: java org.greenstone.server.Server3 <gsdl3-src-home> [lang] [-testing_mode]");
			System.exit(1);
		}

		String gsdl3_src_home = args[0];
		File gsdl3_src_dir = new File(gsdl3_src_home);
		if (!gsdl3_src_dir.isDirectory())
		{
			System.err.println("src directory does not exist!");
			System.exit(1);
		}

		String lang = (args.length >= 2) ? args[1] : "en";
		String testingMode = (args.length == 3) ? args[2] : "";
		new Server3(gsdl3_src_home, lang, testingMode);
	}

    // Prepare the log4j.properties for GS3
    protected void initLogger() {

      // this is the web folder
	String gsdl3_home = GlobalProperties.getGSDL3Home(); // may not be initialised at this stage	
	if(gsdl3_home == null) { // use gsdl_home/web
	    gsdl3_home = fallbackGSDL3Home();
	}

	String gsdl3_writablehome = System.getProperty("gsdl3.writablebasedir",gsdl_home) + File.separator + "web";

	String propsFolder = gsdl3_writablehome + File.separator + "WEB-INF" + File.separator + "classes" + File.separator;
	File propsFile = new File(propsFolder+"log4j.properties");

	// create it from the template file GS3/resources/web/log4j.properties
	// Always do this => helps make Greenstone3 portable


	    try {
		// need to set gsdl3.home property's value to be gsdl_home/web,
		// so that the location  of the log files gets resolved correctly
		
		// load the template log4j.properties.svn file into logProps
		FileInputStream infile = new FileInputStream(new File(gsdl_home+File.separator+"resources"+File.separator+"web"+File.separator+"log4j.properties.svn"));
		if(infile != null) {
		    Properties logProps = new Properties();
		    logProps.load(infile);
		    infile.close();

		    // set gsdl3.home to web home
		    logProps.setProperty("gsdl3.home", gsdl3_home);
		    logProps.setProperty("gsdl3.writablehome", gsdl3_writablehome);
		    
		    // write the customised properties out to a custom log4j.properties file
		    FileOutputStream outfile = new FileOutputStream(propsFile);
		    if(outfile != null) {
			logProps.store(outfile, "Customised log4j.properties file");
			outfile.close();
		    } else {
			System.err.println("Could not store properties file " + propsFile + " for Server3.");
		    }
		}
	    } catch(Exception e) {
		System.err.println("Exception occurred when custom-configuring the logger for Server3.\n" + e);
		e.printStackTrace();
	    }

	// now configure the logger with the custom log4j.properties file
	if(propsFile.exists()) {
	    PropertyConfigurator.configure(propsFile.getAbsolutePath());
	} else {
	    System.err.println("Could not create properties file " + propsFile + " for Server3.");
	}
    }
}
