package divconq.tool;

import java.io.File;
import java.io.FileWriter;
import java.util.Scanner;

import divconq.lang.Hub;
import divconq.lang.HubResources;
import divconq.lang.OperationCallback;
import divconq.lang.OperationResult;
import divconq.lang.TaskContext;
import divconq.lang.chars.PigLatin;
import divconq.lang.chars.RtlEnglish;
import divconq.log.DebugLevel;
import divconq.log.Logger;
import divconq.util.StringUtil;
import divconq.xml.XElement;
import divconq.xml.XmlReader;

/**
 * Utility to run a dcDb Sync.  Must run Configure first to get
 * the database settings in config.
 * 
 * Sync is to be used by developers only, and is used to take
 * updates to the local (dev) schema and routines and install them to the database.
 * Only data relevant to the database is uploaded, such as stored procedures
 * and filters as well as locale dictionaries.
 * 
 * @author Andy
 *
 */
public class Sync {
	/*
	 * put Procs/Filters/Locales into M
	 * 
	 * syncDb in Hub
	 * 
	 */
	
	/**
	 * Utility must be run from the application base directory (parent to "bin")
	 * 
	 * @param args ignored
	 */
	public static void main(String[] args) {
		HubResources resources = new HubResources("00001", true);
		resources.setDebugLevel(DebugLevel.Warn);
		OperationResult or = resources.init();
		
		if (or.hasErrors()) {
			Logger.error("Unable to continue, hub resources not properly configured");
			return;
		}
	
		Hub.instance.start(resources);
		
		TaskContext.useNewRoot();
		
		Scanner scan = new Scanner(System.in);
		boolean running = true;
		
		while(running) {
			try {
				System.out.println();
				System.out.println("-----------------------------------------------");
				System.out.println("   DivConq Db Sync Menu");
				System.out.println("-----------------------------------------------");
				System.out.println("0)  Exit");
				System.out.println("1)  Sync Db Routines");
				System.out.println("2)  Sync Db Globals");
				System.out.println("3)  Translate en to pig-latin and rtl-en");

				String opt = scan.nextLine();
				
				Long mopt = StringUtil.parseInt(opt);
				
				if (mopt == null)
					continue;
				
				switch (mopt.intValue()) {
				case 0:
					running = false;
					break;
					
				case 1: {
					Hub.instance.getDatabase().syncScripts(new OperationCallback(true) {			
						@Override
						public void completed() {
							if (this.hasErrors())
								System.out.println("Errors updating routines:\n" + this.toMessage());
							else
								System.out.println("Db Routines updated");				
						}
					});
					
					break;
				}
				case 2:
					Hub.instance.getDatabase().syncSchema(new OperationCallback(true) {
						@Override
						public void completed() {
							if (this.hasErrors())
								System.out.println("Errors updating Db:\n" + this.toMessage());
							else
								System.out.println("Db Schema updated");				
						}
					});
					
					break;
					
				case 3:
					Sync.translate(scan);					
					resources.reloadDictionary();
					break;
				}
						
			}
			catch(Exception x) {
				System.out.println("CLI error: " + x);
			}
		}		
		
		Hub.instance.stop();
		
	}
	
	/**
	 * Loop the packages and prompt for translation, if yes then a x-pig-latin and x-rtl-en
	 * variation of the en tokens is generated  
	 * 
	 * @param scan user input scanner
	 */
	private static void translate(Scanner scan) {
		System.out.println();
		System.out.println("Loop packages, type 'yes' for packages you wish to translate. ");
		System.out.println("When 'yes' note that the existing pig-latin an rtl-en files will");
		System.out.println("be overwritten. (skips zipped packages, for dev only)");
		System.out.println();
				
		File pkgs = new File("./packages");
		
		for (File pkg : pkgs.listFiles()) {
			if (!pkg.isDirectory()) 
				continue;
				
			String name = pkg.getName();
			
			System.out.println("Found: " + name);
			System.out.print("[yes/no]: ");
			
			if (!"yes".equals(scan.nextLine().toLowerCase()))
				continue;
			
			for (File safety : pkg.listFiles()) {
				if (!safety.isDirectory()) 
					continue;
				
				File dictdir = new File(safety, "dictionary");
				
				if (!dictdir.exists() || !dictdir.isDirectory()) 
					continue;
				
				File en = new File(dictdir, "en.xml");
				
				if (!en.exists())
					en = new File(dictdir, "dictionary.xml");
				
				if (!en.exists())
					continue;
				
				// pig latin translation
				
				File pltr = new File(dictdir, "x-pig-latin.xml");
				XElement trroot = XmlReader.loadFile(en);
				
				try {
					FileWriter fw = new FileWriter(pltr);
					fw.append("<Dictionary>\n");
					fw.append("<Locale Id=\"x-pig-latin\">\n");
	
					for (XElement lel : trroot.selectAll("Locale")) {
						String lname = lel.getAttribute("Id");
						
						if (!"en".equals(lname))
							continue;
						
						for (XElement tel : lel.selectAll("Entry")) {
							String tname = tel.getAttribute("Token");
							
							if (StringUtil.isEmpty(tname))
								continue;
							
							String v = tel.getAttribute("Value");
							
							if (StringUtil.isEmpty(v))
								v = tel.getText();
							
							if (StringUtil.isEmpty(v))
								continue;
							
							fw.append("\t<Entry Token=\"" + tname + "\" Value=\"" + PigLatin.translate(v) + "\" />\n");
						}
					}
					
					fw.append("</Locale>\n");
					fw.append("</Dictionary>\n");
					
					fw.flush();
					fw.close();
				}
				catch (Exception x) {
					System.out.println("Problem translating file to pig-latin: " + en.getAbsolutePath());
					System.out.println("Error: " + x);
				}
				
				// rtl-en translation
				pltr = new File(dictdir, "x-rtl-en.xml");
				
				try {
					FileWriter fw = new FileWriter(pltr);
					fw.append("<Dictionary>\n");
					fw.append("<Locale Id=\"x-rtl-en\">\n");
	
					for (XElement lel : trroot.selectAll("Locale")) {
						String lname = lel.getAttribute("Id");
						
						if (!"en".equals(lname))
							continue;
						
						for (XElement tel : lel.selectAll("Entry")) {
							String tname = tel.getAttribute("Token");
							
							if (StringUtil.isEmpty(tname))
								continue;
							
							String v = tel.getAttribute("Value");
							
							if (StringUtil.isEmpty(v))
								v = tel.getText();
							
							if (StringUtil.isEmpty(v))
								continue;
							
							fw.append("\t<Entry Token=\"" + tname + "\" Value=\"" + RtlEnglish.translate(v) + "\" />\n");
						}
					}
					
					fw.append("</Locale>\n");
					fw.append("</Dictionary>\n");
					
					fw.flush();
					fw.close();
				}
				catch (Exception x) {
					System.out.println("Problem translating file to pig-latin: " + en.getAbsolutePath());
					System.out.println("Error: " + x);
				}
			}
		}
	}
}
