/*
 * Filename: Launcher.java
 *
 * Author: Joe Wang
 *
 * Copyright (c) 2003-2005 
 * The Trustees of Columbia University in the City of New York
 * Columbia University Information Technology
 *
 * This file is part of NINJa.
 *
 * NINJa is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * NINJa is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with NINJa; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Created on April 23, 2003, 10:17 AM
 */

package edu.columbia.print.ninja.prix;

import java.io.*;
import java.util.*;
import java.util.prefs.*;
import java.util.regex.*;
import java.net.*;


/**
 *
 * @author  joe
 */
public class Launcher {
    
    /** Creates a new instance of Launcher */
    public Launcher() {
    }
    
    static class Emptier implements Runnable {
        InputStream is;
        Emptier(InputStream is) { this.is = is; }
        public void run() {
            try {
                for(int value=0; (value=is.read())>=0;);
                is.close();
            }
            catch(IOException e) {
            }
        }
    }

    static class FileEmptier implements Runnable {
        InputStream is;
        String file;
        FileEmptier(String file, InputStream is) {
            this.file = file;
            this.is = is;
        }
        public void run() {
            try {
                FileOutputStream os = new FileOutputStream(file, true);
                for(int value=0; (value=is.read())>=0;) os.write(value);
                is.close();
                os.close();
            }
            catch(IOException e) {
            }
        }
    }

    public static void deleteAll(File file) {
        if(file.isDirectory()) {
            File[] files = file.listFiles();
            for(int i=files.length-1; i>=0; i--) deleteAll(files[i]);
        }
        file.delete();
    }

    public static void main(String[] args) {
        try {
            Preferences prefs = Preferences.userRoot().node("edu/columbia/print/ninja/prix");
            File persistentLog;
            Set props = System.getProperties().entrySet();
            String javaHome = System.getProperty("java.home");
            String installDir = prefs.get("installDir", null);
            if(File.separatorChar=='\\') {
                StringTokenizer t = new StringTokenizer(installDir, "\\");
                installDir = "";
                for(;t.hasMoreTokens();) {
                    String file = t.nextToken();
                    if(file.indexOf(" ")>=0) {
                        file = file.replaceAll(" ", "").toUpperCase();
                        if(file.length()>6) file = file.substring(0,6);
                        file += "~1";
                    }
                    installDir += file+"\\";
                }
            }
            String hostName = java.net.InetAddress.getLocalHost().getCanonicalHostName();
            Vector cmd = new Vector();
            String sep = System.getProperty("file.separator");
            File libDir = new File(installDir+sep+"code");
            Set ignore = new HashSet();
            ignore.add("line.separator");
            ignore.add("java.runtime.name");
            ignore.add("sun.boot.library.path");
            ignore.add("java.vm.vendor");
            ignore.add("path.separator");
            ignore.add("java.vm.name");
            ignore.add("jnlpx.home");
            ignore.add("java.vm.specification.name");
            ignore.add("user.dir");
            ignore.add("user.home");
            ignore.add("java.endorsed.dirs");
            ignore.add("java.vm.specification.vendor");
            ignore.add("os.name");
            ignore.add("java.library.path");
            ignore.add("java.specification.name");
            ignore.add("java.class.path");
            ignore.add("java.home");
            ignore.add("java.ext.dirs");
            ignore.add("sun.boot.class.path");
            ignore.add("java.vendor");
            ignore.add("file.separator");
            ignore.add("jnlpx.jvm");
            ignore.add("sun.cpu.isalist");

            //stop rmid
            cmd.clear();
            cmd.add(javaHome+sep+"bin"+sep+"rmid");
            cmd.add("-stop");
            System.out.println("Stopping rmid:");
            for(Iterator i=cmd.iterator(); i.hasNext();) System.out.println("  "+i.next());
            Process p0 = Runtime.getRuntime().exec((String[] )cmd.toArray(new String[cmd.size()]));
            new Thread(new Emptier(p0.getInputStream())).start();
            new Thread(new Emptier(p0.getErrorStream())).start();
            p0.waitFor();
            System.out.println("rmid exited: "+p0.exitValue());

            //start rmid
            persistentLog = new File(new File(installDir), "rmid.log");
            deleteAll(persistentLog);
            cmd.clear();
            cmd.add(javaHome+sep+"bin"+sep+"rmid");
            cmd.add("-J-Dsun.rmi.activation.execPolicy=none");
            for(Iterator i=props.iterator(); i.hasNext();) {
                Map.Entry entry = (Map.Entry )i.next();
                if(ignore.contains(entry.getKey())) continue;
                cmd.add("-C-D"+entry.getKey()+"="+entry.getValue());
            }
            cmd.add("-C-Dlib.dir="+libDir.toURI());
            cmd.add("-C-Dlocalhost="+hostName);
            cmd.add("-log");
            cmd.add(persistentLog.getAbsolutePath());
            System.out.println("Starting rmid:");
            for(Iterator i=cmd.iterator(); i.hasNext();) System.out.println("  "+i.next());
            Process p = Runtime.getRuntime().exec((String[] )cmd.toArray(new String[cmd.size()]));
            String rmidLog = System.getProperty("rmid.log");
            if(rmidLog==null) {
                new Thread(new Emptier(p.getInputStream())).start();
                new Thread(new Emptier(p.getErrorStream())).start();
            }
            else {
                new Thread(new FileEmptier(rmidLog, p.getInputStream())).start();
                new Thread(new FileEmptier(rmidLog, p.getErrorStream())).start();
            }
            Thread.sleep(2000);

            //start prix
            System.out.println("Starting prix:");
            persistentLog = new File(new File("installDir"), "prix.log");
            deleteAll(persistentLog);
            cmd.clear();
            cmd.add(javaHome+sep+"bin"+sep+"java");
            for(Iterator i=props.iterator(); i.hasNext();) {
                Map.Entry entry = (Map.Entry )i.next();
                if(ignore.contains(entry.getKey())) continue;
                if("java.security.policy".equals(entry.getKey())) continue;
                cmd.add("-D"+entry.getKey()+"="+entry.getValue());
            }
            cmd.add("-Djava.security.policy="+args[0]);
            cmd.add("-jar");
            cmd.add(installDir+sep+"code"+sep+"loader.jar");
            cmd.add(installDir+sep+"code");
            cmd.add(installDir+sep+"code");
            cmd.add("edu.columbia.print.ninja.prix.Prix");
            cmd.add("prix.jar");
            cmd.add("prix-dl.jar cybernode-dl.jar rio-dl.jar");
            cmd.add("-name");
            cmd.add(hostName);
            cmd.add("-logDir");
            cmd.add(installDir+sep+"prix.log");
            for(int i=1; i<args.length; i++) cmd.add(args[i]);
            for(Iterator i=cmd.iterator(); i.hasNext();) System.out.println("  "+i.next());
            Process p2 = Runtime.getRuntime().exec((String[] )cmd.toArray(new String[cmd.size()]));
            String prixLog = System.getProperty("prix.log");
            if(prixLog==null) {
                new Thread(new Emptier(p2.getInputStream())).start();
                new Thread(new Emptier(p2.getErrorStream())).start();
            }
            else {
                new Thread(new FileEmptier(prixLog, p2.getInputStream())).start();
                new Thread(new FileEmptier(prixLog, p2.getErrorStream())).start();
            }
            p2.waitFor();
            System.out.println("Startup complete:");
        }
        catch(Exception e) {
            System.out.println(e+"");
            e.printStackTrace();
        }
    }
    
}
