//   Licensed to the Apache Software Foundation (ASF) under one or more
//   contributor license agreements.  See the NOTICE file distributed with
//   this work for additional information regarding copyright ownership.
//   The ASF licenses this file to You under the Apache License, Version 2.0
//   (the "License"); you may not use this file except in compliance with
//   the License.  You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//   $Id$ -->

// jscript to run FOP, adapted from the Jakarta-Ant project.

// rpm_mode is irrelevant on Windows
// var rpm_mode=true;
var fop_exec_args = "";
var no_config=false;
var fop_exec_debug=false;
var debug=false;
var keep_open=false;
var show_help=false;

var config_wanted = new Array("FOP_HOME", "CLASSPATH", "FOP_HYPHENATION_PATH", "FOP_OPTS", "JAVA_OPTS", "LOGCHOICE", "LOGLEVEL");

// parse command-line arguments
function read_args() {
  var args = WScript.Arguments;
  var named = new ActiveXObject("Scripting.Dictionary");
  for (i = 0; i < args.length; i++) {
	switch(args(i)) {
	case "--debug":
	  debug=true;
	  break;
	case "--execdebug":
	  fop_exec_debug=true;
	  break;
	case "--keepopen":
	  keep_open=true;
	  break;
	case "--noconfig":
	  no_config=true;
	  break;
	case "-h":
	case "--help":
	case "--h":
	case "-help":
	  show_help=true;
	  // fop_exec_args=fop_exec_args + " -h";
	  break;
	default:
	  fop_exec_args=fop_exec_args + " " + args(i);
	}
  }
  if (debug) {
	WScript.Echo("debug: " + debug);
	WScript.Echo("execdebug: " + fop_exec_debug);
 	WScript.Echo("keepopen: " + keep_open);
 	WScript.Echo("noconfig: " + no_config);
	WScript.Echo("help: " + show_help);
 	WScript.Echo("fop arguments: " + fop_exec_args);
  }
}

var help_text="Usage:\n"
  + WScript.ScriptFullName + " [script options] [FOP options]\n"
  + "Script Options:\n"
  + "  --help, -h             print this message and FOP help\n"
  + "  --debug                print debugging information for this launch script\n"
  + "  --execdebug            print FOP exec line generated by this launch script\n"
  + "  --keepopen             keep FOP's command window open\n"
  + "  --noconfig             suppress reading of configuration file and registry";

function read_environment() {
  for (i in config_wanted) {
	if (!config.Exists(config_wanted[i])) {
		var env_var_string = "%" + config_wanted[i] + "%";
		var env_var = shell.ExpandEnvironmentStrings(env_var_string);
		if (env_var != "" && env_var != env_var_string) {
		  config.Add(config_wanted[i], env_var);
		  if (debug) {
			WScript.Echo(config_wanted[i] + " env: "
						 + config.Item(config_wanted[i]));
		  }
		}
	}
  }
}

function read_desktop(dtname) {
  if (fs.FolderExists(dtname)) {
	var fopname = fs.GetFolder(dtname).ParentFolder.Path
	  + "\\Application Data\\Fop";
	if (fs.FolderExists(fopname)) {
	  var fop_conf_name = fs.GetFolder(fopname).Path + "\\fop.conf";
	  if (fs.FileExists(fop_conf_name)) {
		// source fop_conf_file
		var conf_file = fs.openTextFile(fs.GetFile(fop_conf_name));
		var conf_lines = new ActiveXObject("Scripting.Dictionary");
		while (!conf_file.AtEndOfStream) {
		  var line = conf_file.ReadLine();
		  var m = line.match(/(.+?)=(.+)/);
		  if (m != null) {
			conf_lines.Add(m[1], m[2]);
		  }
		}
		for (j in config_wanted) {
		  if (!config.Exists(config_wanted[j])
			  && conf_lines.Exists(config_wanted[j])) {
			config.Add(config_wanted[j], conf_lines.Item(config_wanted[j]));
			if (debug) {
			  WScript.Echo(config_wanted[j] + " " + dts[i] + ": "
						   + config.Item(config_wanted[i]));
			}
		  }
		}
	  }
	}
  }
}

function read_registry(section) {
  for (j in config_wanted) {
	if (!config.Exists(config_wanted[j])) {
	  var reg_var;
	  try {
		reg_var = shell.RegRead(section + "\\Software\\Fop\\"
								+ config_wanted[j]);
		config.Add(config_wanted[j], reg_var);
		if (debug) {
		  WScript.Echo(config_wanted[j] + " " + rks[i] + ": "
					   + config.Item(config_wanted[j]));
		}
	  } catch(e) {}
	}
  }
}

// construct FOP_HOME from the script folder
function get_fop_home() {
  if (!config.Exists("FOP_HOME")
	  || !fs.FolderExists(config.Item("FOP_HOME"))) {
	var fop_home = WScript.ScriptFullName;
	fop_home = fop_home.substring(0, fop_home.length
								  - WScript.ScriptName.length - 1);
	if (config.Exists("FOP_HOME")) {
	  config.Remove("FOP_HOME");
	}
	config.Add("FOP_HOME", fop_home);
	if (debug) {
	  WScript.Echo("FOP_HOME dyn: " + config.Item("FOP_HOME"));
	}
  }
}

function get_java_cmd() {
  var java_home = shell.ExpandEnvironmentStrings("%JAVA_HOME%");
  javacmd = "java";
  if (java_home != "" && typeof(java_home) != "undefined"
	  && fs.FolderExists(java_home)) {
	var javacmd_candidate = java_home + "\\bin\\java.exe";
	if (fs.FileExists(javacmd_candidate)) {
	  javacmd = javacmd_candidate;
	}
  }
  if (debug) {
	WScript.Echo("java command: " + javacmd);
  }
}

function get_local_classpath() {
  if (config.Exists("CLASSPATH")) {
	local_classpath = config.Item("CLASSPATH");
	if (debug) {
	  WScript.Echo("local classpath: " + local_classpath);
	}
  }

  // add fop.jar, fop-sandbox and fop-hyph.jar, which reside in $FOP_HOME/build
  var lcp = local_classpath;
  local_classpath = config.Item("FOP_HOME") + "\\build\\fop.jar;"
	+ config.Item("FOP_HOME") + "\\build\\fop-sandbox.jar;"
	+ config.Item("FOP_HOME") + "\\build\\fop-hyph.jar";
  if (lcp != "") {
	local_classpath += ";" + lcp;
  }
  if (debug) {
	WScript.Echo("local classpath: " + local_classpath);
  }

  // add in the dependency .jar files, which reside in $FOP_HOME/lib
  var libdir_name = config.Item("FOP_HOME") + "\\lib";
  var dirlibs;
  if (fs.FolderExists(libdir_name)) {
	dirlibs = fs.GetFolder(libdir_name).Files;
	var e = new Enumerator(dirlibs);
	for (; !e.atEnd(); e.moveNext()) {
	  if (e.item().Name.match("\.jar$")) {
		local_classpath = libdir_name + "\\" + e.item().Name + ";" + local_classpath;
	  }
	}
	if (debug) {
	  WScript.Echo("local classpath: " + local_classpath);
	}
  }

  // add in user-defined hyphenation JARs
  if (config.Exists("FOP_HYPHENATION_PATH")) {
	local_classpath += ";" + config.Item("FOP_HYPHENATION_PATH");
	if (debug) {
	  WScript.Echo("local classpath: " + local_classpath);
	}
  }
}

// Execute fop via shell.Exec
function fop_exec() {
  var fop_exec_command = "\"" + javacmd + "\" "
	+ (config.Exists("JAVA_OPTS")?config.Item("JAVA_OPTS") + " ":"")
	+ (config.Exists("LOGCHOICE")?config.Item("LOGCHOICE") + " ":"")
	+ (config.Exists("LOGLEVEL")?config.Item("LOGLEVEL") + " ":"")
	"-classpath \"" + local_classpath + "\" "
	+ (config.Exists("FOP_OPTS")?config.Item("FOP_OPTS"):"")
	+ "org.apache.fop.cli.Main " + fop_exec_args;
  if (debug || fop_exec_debug) {
	WScript.Echo(fop_exec_command);
  }

  var fop_run = shell.Exec(fop_exec_command);
  while (true) {
	while (!fop_run.StdOut.AtEndOfStream) {
	  WScript.Echo(fop_run.StdOut.ReadLine());
	}
	while (!fop_run.StdErr.AtEndOfStream) {
	  WScript.Echo(fop_run.StdErr.ReadLine());
	}
	if (fop_run.Status == 1) {
	  break;
	}
	WScript.Sleep(100);
  }
  if (debug) {
	WScript.Echo("exit status: " + fop_run.ExitCode);
  }
}

// Execute fop via shell.Run
function fop_run() {
  var fop_exec_command = "cmd /" + (keep_open?"K":"C") + " \""
	+ "\"" + javacmd + "\" " 
	+ (config.Exists("JAVA_OPTS")?config.Item("JAVA_OPTS") + " ":"")
	+ (config.Exists("LOGCHOICE")?config.Item("LOGCHOICE") + " ":"")
	+ (config.Exists("LOGLEVEL")?config.Item("LOGLEVEL") + " ":"")
	+ "-classpath \"" + local_classpath + "\" "
	+ (config.Exists("FOP_OPTS")?config.Item("FOP_OPTS") + " ":"")
	+ "org.apache.fop.cli.Main " + fop_exec_args + "\"";
  if (debug || fop_exec_debug) {
	WScript.Echo(fop_exec_command);
  }
  var exit_code = shell.Run(fop_exec_command, 1, 1);
  if (debug) {
	WScript.Echo("exit status: " + exit_code);
  } else {
	if (exit_code != 0) {
	  WScript.Echo("A FOP error occurred (FOP exit status: " + exit_code + ")\n"
	               + "Use option --keepopen to see FOP's output\n"
                       + "(that is two dashes)");
	}
  }
}

function get_log_choice() {
  // The default commons logger for JDK1.4 is JDK1.4Logger.
  // To use a different logger, uncomment the one desired below
  if (!config.Exists("LOGCHOICE")) {
	// config.Add("LOGCHOICE","\"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog\"");
	// config.Add("LOGCHOICE","\"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog\"");
	// config.Add("LOGCHOICE","\"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger\"");
	if (debug && config.Exists("LOGCHOICE")) {
	  WScript.Echo("LOGCHOICE script: " + config.Item("LOGCHOICE"));
	}
  }
}

function get_log_level() {
  // Logging levels
  // Below option is only if you are using SimpleLog instead of the default JDK1.4 Logger.
  // To set logging levels for JDK 1.4 Logger, edit the %JAVA_HOME%/JRE/LIB/logging.properties 
  // file instead.
  // Possible SimpleLog values:  "trace", "debug", "info" (default), "warn", "error", or "fatal".
  if (!config.Exists("LOGLEVEL")) {
	// config.Add("LOGLEVEL","\"-Dorg.apache.commons.logging.simplelog.defaultlog=INFO\"");
	if (debug && config.Exists("LOGLEVEL")) {
	  WScript.Echo("LOGLEVEL script: " + config.Item("LOGLEVEL"));
	}
  }
}

var shell = WScript.CreateObject("WScript.Shell");
var fs = WScript.CreateObject("Scripting.FileSystemObject");

// configuration
var config = new ActiveXObject("Scripting.Dictionary");

read_args();
read_environment();
if (!no_config) {
  // read user and system-wide fop configurations
  var spec = shell.SpecialFolders;
  var dts = new Array("Desktop", "AllUsersDesktop");
  for (i in dts) {
	read_desktop(spec(dts[i]));
  }
  // read user and system-wide registry
  var rks = new Array("HKCU", "HKLM");
  for (i in rks) {
	read_registry(rks[i]);
  }
}

get_fop_home();
get_log_choice();
get_log_level();
var javacmd = "";
get_java_cmd();
var local_classpath = "";
get_local_classpath();

// Show script help if requested
if (show_help) {
  // fop_exec_args = "";
  keep_open = true;
  WScript.Echo(help_text);
}

// fop_exec();
fop_run();
