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

        try {
            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")) {
                        File pFile = new File(bindir).getParentFile();
                        if (pFile != null)
                            dir = Utils
                                    .escapeBackSlash(pFile.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", "");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        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;
    }

}
