//   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();
