/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/01/11, 17:54
!  AUTHOR(S): KOGA, Junichiro
!  File : ExecScriptCreator.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.scriptexecscripts;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.log4j.Logger;

import ciss.phase_viewer.main.PluginLoader;
import ciss.phase_viewer.scripting.ScriptWrapper;
import ciss.phase_viewer.ssh.hosts.HostInfo;

/**
 * ScriptExecScriptをインスタンス化
 * 
 * @author
 */
public class ExecScriptCreator {
    private static Logger logger = Logger.getLogger(ExecScriptCreator.class
            .getName());

    /** Creates a new instance of ExecScriptCreator */
    private ExecScriptCreator() {
    }

    /**
     * 「スクリプト実行用のスクリプト」を作成し, そのパスを返す. ファイルはテンポラリーディレクトリー下に作成される.
     * ScriptWrapperの配列を渡す際にはこっちをつかう.
     * 
     * @param scriptType
     *            スクリプト種; ScriptWrapper.REGISTERED_SCRIPT_TYPEのなかから選ぶこと.
     * @param execScripts
     *            実際に計算ホストに投げるスクリプトの配列.
     * @return 作成されたスクリプトファイルへのパス; テンポラリーディレクトリーに作成される.
     */
    public static String getScriptExecScript(String scriptType,
            ScriptWrapper[] execScripts, HostInfo hostInfo) {
        if (execScripts == null || execScripts.length == 0) {
            logger.error("no exec scripts.");
            return "";
        }
        String[] string = new String[execScripts.length];
        for (int i = 0; i < execScripts.length; i++) {
            string[i] = new File(execScripts[i].getPath()).getName();
        }
        String ret = getScriptExecScript(scriptType, string, hostInfo);
        return ret;
    }

    /**
     * 「スクリプト実行用のスクリプト」を作成し, そのパスを返す. ファイルはテンポラリーディレクトリー下に作成される.
     * 
     * @param scriptType
     *            スクリプト種; ScriptWrapper.REGISTERED_SCRIPT_TYPEのなかから選ぶこと.
     * @param execScripts
     *            実際に計算ホストに投げるスクリプトの名前の配列.
     * @return 作成されたスクリプトファイルへのパス; テンポラリーディレクトリーに作成される.
     */
    public static String getScriptExecScript(String scriptType,
            String[] execScripts, HostInfo hostInfo) {
        if (execScripts == null || execScripts.length == 0) {
            logger.error("no exec scripts.");
            return "";
        }

        ScriptExecScript execscript = getScriptExecScriptSub(scriptType);

        if (execscript == null) {
            logger.error("failed to get exec script creator.");
            return "";
        }

        String file = System.getProperty("java.io.tmpdir");
        // file +=
        // System.getProperty("file.separator")+execscript.getScriptExecScriptName(hostInfo);
        if (!file.endsWith(System.getProperty("file.separator"))) {
            file += System.getProperty("file.separator");
        }
        file += execscript.getScriptExecScriptName(hostInfo);

        String script = execscript
                .createScriptExecScript(execScripts, hostInfo);

        BufferedWriter bwriter = null;
        try {
            new File(file).delete();
            bwriter = new BufferedWriter(new FileWriter(file));
            bwriter.write(script, 0, script.length());
            bwriter.flush();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            try {
                bwriter.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }

        return file;
    }

    /**
     * 「スクリプトを実行するスクリプトを実行するスクリプト」を作成し, そのパスを返す.
     * 
     * @param scriptType
     *            スクリプト種
     * @param scriptExecScript
     *            スクリプトを実行するスクリプトのパス
     * @param isLocal
     *            ターゲットホストがローカルホストかいなか.
     * @return ここで作成されるスクリプトのパス.
     */
    public static String getScriptExecScriptExecString(String scriptType,
            String scriptExecScript, HostInfo hostInfo) {
        ScriptExecScript execscript = getScriptExecScriptSub(scriptType);
        return execscript.getScriptExecScriptExecString(scriptExecScript,
                hostInfo);
    }

    private static ScriptExecScript getScriptExecScriptSub(String scriptType) {
        boolean registered = false;
        for (int i = 0; i < ScriptWrapper.REGISTERED_SCRIPT_TYPE.length; i++) {
            if (scriptType.equals(ScriptWrapper.REGISTERED_SCRIPT_TYPE[i])) {
                registered = true;
                break;
            }
        }

        if (!registered) {
            logger.error("unsupported script type!");
            return null;
        }

        Properties props = new Properties();
        InputStream inp = null;
        try {
            inp = ExecScriptCreator.class
                    .getResourceAsStream("/ciss/phase_viewer/scripting/scriptexecscripts/scriptexecscripts.properties");
            props.load(inp);
        } catch (IOException ioe) {
            logger.error("failed to load property file...");
        } finally {
            try {
                inp.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }

        String loadClass = props.getProperty(scriptType);
        if (loadClass == null || loadClass.trim().length() == 0) {
            logger.error("invalid properties file...");
            return null;
        }

        ScriptExecScript execscript = (ScriptExecScript) PluginLoader
                .instantiate(loadClass, null);
        return execscript;
    }

}
