/*	2010-11-05
 */
package sigml2gsigml;


import java.util.Arrays;
import java.io.IOException;
import java.io.File;
import java.io.BufferedReader;
import java.io.PrintStream;

import sigmlinlib.SiGMLInLib;

import static sigmlinlib.SiGMLInLib.ASI_SIGML_IN;
import static sigmlinlib.SiGMLInLib.ASI_SIGML_GESTURAL;
import static sigmlinlib.SiGMLInLib.ASI_SIGML_IN_ERR_COUNT;
import static sigmlinlib.SiGMLInLib.ASI_SIGML_ERROR_TEXT;

import static util.HNSUtils.getStdBufReader;
import static util.HNSUtils.getBufReader;
import static util.HNSUtils.readLines;
import static util.HNSUtils.joinLines;
import static util.HNSUtils.filePrintStream;
import static util.HNSUtils.toStdOut;
import static util.HNSUtils.toStream;


/** Main class for the (arbitrary) SiGML to Gestural SiGML Converter. */
public class Main {

/** Converts arbitrary SiGML to Gestural SiGML, using SiGMLInLib.
 * There are two modes of operation: either a single input SiGML document
 * is supplied on standard input, or as a file whose path is specified
 * by the first and only argument, or input and output directories of
 * SiGML files are specified, via a two- or three- argument sequence of the
 * form {@code -d in_dir [out_dir]}, where, if it is not explicitly
 * specified, the output directory path is obtained by appending
 * {@code -g} to that of the input directory.  In the first mode the
 * result is provided on standard output.
 * In the second mode, the output directory should not exist already,
 * and each file in the input directory whose name ends with {@code
 * .sigml} is converted to a corresponding file, with name ending
 * in {@code -g.sigml}, in the output directory.
 * Whatever its source, each input document should be UTF-8,
 * and each output document is provided as UTF-8.
 */
	public static void main(String[] args) throws IOException {

		if (args != null && 2 <= args.length && args[0].equals("-d")) {

			convertDir(args);
		}
		else {
			int pathix = -1;
			int hmlix = -1;

			if (args != null && args.length != 0) {

				if (args.length == 1) {
					if (args[0].startsWith("-")) { hmlix = 0; }
					else { pathix = 0; }
				}
				else if (args.length == 2) {
					pathix = 0;
					if (2 <= args[1].length()) { hmlix = 1; }
				}
				else {
					System.err.println("args:  [ <sigml-file> ] [ -hml ]");
				}
			}

			final String PATH = pathix < 0 ? null : args[pathix];
			final boolean SHOW_HML =  0 <= hmlix  && "-hml".startsWith(args[hmlix]);

			BufferedReader hrdr =
				PATH == null ? getStdBufReader() : getBufReader(PATH);

			final SiGMLInLib SIL = new SiGMLInLib();
			// Use this new facility only if we need it -- meaning
			// that if we don't we should avoid breaking if running
			// with an old SiGMLInLib.
			if (SHOW_HML) { SIL.setEnabledLogHML(SHOW_HML); }

			String[] hsigml = readLines(hrdr);
			String hsigmldoc = joinLines(hsigml);

			String[] tog = SIL.sigmlSignsToGestural(hsigmldoc);

			if (!tog[ASI_SIGML_IN_ERR_COUNT].equals("0")) {
				String errmsg = tog[ASI_SIGML_ERROR_TEXT];
				System.err.println(
					"SiGML conversion error(s):");
				System.err.println(errmsg);
				System.err.println(
					"SiGML conversion error count: "+
					tog[ASI_SIGML_IN_ERR_COUNT]);
			}

			// Try to produce some output even if there were errors.
			String[] gsigml = tog[ASI_SIGML_GESTURAL].split("\n");
			toStdOut(gsigml);
		}
	}

/** Converts a directory of HNS SiGML files, generating a directory of
 * Gestural SiGML files.
 */
	private static void convertDir(String[] args)
	throws IOException {

		final String IN_DIR_S = args[1];
		final String OUT_DIR_S =
			3 <= args.length ? args[2] : IN_DIR_S+"-g";

		final File IN_DIR = new File(IN_DIR_S);
		final File OUT_DIR = new File(OUT_DIR_S);

		if (! IN_DIR.exists()) {
			System.err.println("Missing directory: "+IN_DIR_S);
		}
		if (OUT_DIR.exists()) {
			System.err.println(
				"Directory (or file) already exists: "+OUT_DIR_S);
		}
		else {
			boolean outok = OUT_DIR.mkdirs();
			if (!outok) {
			System.err.println(
				"Directory creation failure: "+OUT_DIR_S);
			}
			else {
				convertDir(IN_DIR, OUT_DIR);
			}
		}
	}

	private static void convertDir(final File IN_DIR, final File OUT_DIR)
	throws IOException {

		final SiGMLInLib SIGML_IN_LIB = new SiGMLInLib();

		final String[] S_STEMS = sigmlStems(IN_DIR);
		for (String sstem : S_STEMS) {
			BufferedReader srdr = getBufReader(IN_DIR+"/"+sstem+".sigml");

			String[] sigml = readLines(srdr);
			String sigmldoc = joinLines(sigml);

			String[] tog = SIGML_IN_LIB.sigmlSignsToGestural(sigmldoc);
			if (tog[ASI_SIGML_IN_ERR_COUNT].equals("0")) {
				String[] gsigml = tog[ASI_SIGML_GESTURAL].split("\n");
				final String GS_FILE = sstem+"-g.sigml";
				PrintStream gsout = filePrintStream(OUT_DIR, GS_FILE);
				toStream(gsigml, gsout);
				gsout.close();
			}
			else {
				String errmsg = tog[ASI_SIGML_ERROR_TEXT];
				System.err.println(
					"SiGML conversion error(s) for "+sstem+".sigml: ");
				System.err.println(errmsg);
			}
		}
	}

	private static String[] sigmlStems(final File DIR) {

		final String TAIL = ".sigml";
		final int T_LEN = TAIL.length();
		String[] fnames = DIR.list();
		Arrays.sort(fnames);
		final int N = fnames.length;
		for (int i=0; i!=N; ++i) {
			String fnm = fnames[i];
			if (fnm.endsWith(TAIL)) {
				fnames[i] = fnm.substring(0, fnm.length()-T_LEN);
			}
		}
		return fnames;
	}
}
