/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/01/13, 20:53
!  AUTHOR(S): KOGA, Junichiro
!  File : BasicScriptReplaceRules.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */

package ciss.phase_viewer.scripting.scriptreplace;

import java.io.File;

import org.apache.log4j.Logger;
import org.jdom.Element;

import ciss.phase_viewer.common.Utils;
import ciss.phase_viewer.jdom.MyElement;
import ciss.phase_viewer.jobcontrol.JobController;

/**
 * 基本的な置換規則.
 * 
 * @author
 */
public class BasicScriptReplaceRules extends ScriptReplaceRules {
    private Logger logger = Logger.getLogger(BasicScriptReplaceRules.class
            .getName());

    private final String __MPIRUN__ = "__MPIRUN__";
    private final String __MPIEXEC__ = "__MPIEXEC__";

    private final String __TARGETDIR__ = "__TARGETDIR__";
    private final String __JAVADIR__ = "__JAVADIR__";
    private final String __NP__ = "__NP__";
    private final String __N__ = "__N__";
    private final String __FS__ = "__FS__";
    private final String __BINDIR__ = "__BINDIR__";

    private final String __JAVA__ = "__JAVA__";
    private final String __CHASEJAR__ = "__CHASEJAR__";
    private final String __CHASEDIR__ = "__CHASEDIR__";

    private final String __NP0__ = "__NP0__";

    private String[] keys = { __MPIRUN__, __MPIEXEC__, __TARGETDIR__, __JAVA__,
            __JAVADIR__, __NP__, __N__, __FS__, __BINDIR__, __CHASEJAR__,
            __CHASEDIR__, __NP0__ };

    /** Creates a new instance of BasicScriptReplaceRules */
    public BasicScriptReplaceRules() {
    }

    public String replace(String script, org.jdom.Document document,
            boolean overwrite) {
        if (document == null || !document.hasRootElement()) {
            logger.error("invalid document");
            return null;
        }

        Element mpiParams = document.getRootElement().getChild("MPI_Params");
        if (mpiParams == null) {
            logger.warn("invalid mpiparams... using defaults");
        }

        Element jobcontrol = document.getRootElement().getChild(
                JobController.JOBCONTROL);
        if (jobcontrol == null) {
            logger.error("invalid jobcontrol element");
            return null;
        }

        Element targethost = jobcontrol.getChild("targethost");
        if (targethost == null) {
            logger.error("invalid 'targethost' element");
            return null;
        }

        Element env = targethost.getChild("env");
        if (env == null) {
            logger.error("invalid 'env' element");
            return null;
        }

        String[] keys = getKeys();

        for (int i = 0; i < keys.length; i++) {
            String key = keys[i];
            if (key.equals(__MPIRUN__)) {
                String mpidir = MyElement
                        .decode(env.getChildTextTrim("mpidir"));
                String mpirun = mpidir + "/bin/mpirun";
                if (mpidir == null || mpidir.trim().length() == 0) {
                    mpirun = "mpirun";
                }

                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    boolean wmpi = mpiSupport(env, targethost.getTextTrim());
                    mpidir = getMPIbinDirWin(mpidir);
                    if (!wmpi)
                        mpirun = "";
                    else {
                        if (mpidir == null)
                            mpirun = "\"" + "\\\\mpirun.exe" + "\"";
                        else
                            mpirun = "\"" + Utils.escapeBackSlash(mpidir)
                                    + "\\\\mpirun.exe" + "\"";
                    }
                }
                script = script.replaceAll(key, mpirun);
            } else if (key.equals(__MPIEXEC__)) {

                String mpidir = MyElement
                        .decode(env.getChildTextTrim("mpidir"));
                String mpirun = mpidir + "/bin/mpiexec";
                if (mpidir == null || mpidir.trim().length() == 0) {
                    mpirun = "mpiexec";
                }
                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    boolean wmpi = mpiSupport(env, targethost.getTextTrim());
                    mpidir = getMPIbinDirWin(mpidir);
                    if (!wmpi) {
                        mpirun = "";
                    } else {
                        if (mpidir == null)
                            mpirun = "\"" + "\\\\mpiexec.exe" + "\"";
                        else
                            mpirun = "\"" + mpidir + "\\\\mpiexec.exe" + "\"";
                    }
                }
                script = script.replaceAll(key, mpirun);
            } else if (key.equals(__TARGETDIR__)) {

                String target = MyElement.decode(env
                        .getChildTextTrim("targetdir"));
                if (target == null || target.trim().length() == 0) {
                    target = ".";
                }
                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    target = Utils.escapeBackSlash(target);
                }
                script = script.replaceAll(key, target);
            } else if (key.equals(__NP__) || key.equals(__N__)) {
                String nn = "1";
                if (mpiParams != null) {
                    nn = MyElement.decode(mpiParams.getChildTextTrim("np"));
                    try {
                        Integer.parseInt(nn);
                    } catch (Exception e) {
                        nn = "1";
                    }
                }
                if (!mpiSupport(env, targethost.getTextTrim()))
                    nn = "";
                script = script.replaceAll(key, nn);
            } else if (key.equals(__JAVADIR__)) {

                String javadir = MyElement.decode(env
                        .getChildTextTrim("javadir"));
                if (javadir == null || javadir.trim().length() == 0) {
                    javadir = "";
                }
                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    javadir = Utils.escapeBackSlash(javadir);
                }

                script = script.replaceAll(key, javadir);
            } else if (key.equals(__FS__)) {
                boolean isWindows = new Boolean(MyElement.decode(env
                        .getChildTextTrim("windows"))).booleanValue();
                String FS = "/";
                if (isWindows) {
                    FS = "\\\\";
                }
                script = script.replaceAll(key, FS);
            } else if (key.equals(__BINDIR__)) {
                String bindir = MyElement
                        .decode(env.getChildTextTrim("bindir"));
                if (bindir == null || bindir.trim().length() == 0) {
                    bindir = "";
                }
                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    bindir = Utils.escapeBackSlash(bindir);
                }
                script = script.replaceAll(key, bindir);
            } else if (key.equals(__CHASEJAR__)) {
                String bindir = MyElement
                        .decode(env.getChildTextTrim("bindir"));
                String chase = bindir + "/phase-viewer.jar";
                if (bindir == null || bindir.trim().length() == 0) {
                    chase = "phase-viewer.jar";
                }
                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    chase = Utils.escapeBackSlash(bindir) + "\\\\"
                            + "phase-viewer.jar";
                    if (bindir == null || bindir.trim().length() == 0) {
                        chase = "phase-viewer.jar";
                    }
                }
                script = script.replaceAll(key, chase);
            } else if (key.equals(__CHASEDIR__)) {
                String bindir = MyElement
                        .decode(env.getChildTextTrim("bindir"));
                String dir = "";
                if (bindir != null && bindir.trim().length() != 0) {
                    String[] array = bindir.trim().split("/");
                    String parent = "";
                    for (int j = 0; j < array.length - 1; j++) {
                        if (array[j].trim().length() != 0) {
                            parent += "/" + array[j];
                        }
                    }
                    dir = parent;
                }
                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    dir = Utils.escapeBackSlash(new File(bindir)
                            .getParentFile().getAbsolutePath());
                }
                script = script.replaceAll(key, dir);
            } else if (key.equals(__JAVA__)) {
                String javadir = MyElement.decode(env
                        .getChildTextTrim("javadir"));
                String java = javadir + "/bin/java";
                if (javadir == null || javadir.trim().length() == 0) {
                    java = "java";
                }
                if (targethost.getTextTrim().equals("localhost")
                        && System.getProperty("os.name").toLowerCase()
                                .startsWith("windows")) {
                    java = Utils.escapeBackSlash(javadir) + "\\\\" + "bin"
                            + "\\\\" + "java.exe";
                    if (javadir == null || javadir.trim().length() == 0) {
                        java = "java.exe";
                    }
                }
                script = script.replaceAll(key, java);
            } else if (key.equals(__NP0__)) {
                String np = "";
                if (mpiSupport(env, targethost.getTextTrim()))
                    np = "-np";
                script = script.replaceAll(key, np);
            }
        }

        if (!(targethost.getTextTrim().equals("localhost") && System
                .getProperty("os.name").toLowerCase().startsWith("windows"))) {
            script = script.replaceAll("\\r", "");
        }

        return script;
    }

    private String getMPIbinDirWin(String mpiDir) {
        String test = Utils.escapeBackSlash(mpiDir) + "\\\\" + "bin";

        if (new File(test).exists())
            return test;
        test = Utils.escapeBackSlash(mpiDir) + "\\\\" + "mpirt";
        if (new File(test).exists())
            return test;
        return null;
    }

    public String replace(String script, org.jdom.Document document) {
        return replace(script, document, false);
    }

    protected String[] getKeys() {
        return this.keys;
    }

}
