/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/06/07, 15:36
!  AUTHOR(S): KOGA, Junichiro
!  File : FileTransferPanel.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.file;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

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

import ciss.phase_viewer.common.TaggedString;
import ciss.phase_viewer.jdom.MyElement;
import ciss.phase_viewer.jobcontrol.JobController;
import ciss.phase_viewer.jobcontrol.JobControllerElement;
import ciss.phase_viewer.projectbrowser.ProjectInfo;
import ciss.phase_viewer.scripting.ScriptUtils;
import ciss.phase_viewer.ssh.hosts.HostInfo;
import ciss.phase_viewer.ssh.hosts.HostSelectorCombo;
import ciss.phase_viewer.ssh.remotehostexecuter.BatchFileTransferer;
import ciss.phase_viewer.ssh.sftp.SftpClient;
import ciss.phase_viewer.ssh.terminal.Terminal;

/**
 * "ファイル転送"の設定や実行を支援するGUI.
 * 
 * @author
 */
public class FileTransferPanel extends JPanel implements JobControllerElement {
    private Logger logger = Logger.getLogger(FileTransferPanel.class.getName());

    private ProjectInfo projectInfo;

    private Document doc;

    /**
     * Creates a new instance of FileTransferPanel
     * 
     * @param projectInfo
     *            扱っているプロジェクトの情報を持つオブジェクト
     */
    public FileTransferPanel(ProjectInfo projectInfo) {
        this.projectInfo = projectInfo;
        init();
    }

    public HostInfo getSelectedHost() {
        return hostSelector.getSelectedHost();
    }

    public void setSelectedHost(HostInfo info) {
        hostSelector.setSelectedItem(info.getName());
    }

    public void addActionListenerToHostSelector(ActionListener listener) {
        hostSelector.addActionListener(listener);
        hostSelector.setSelectedIndex(hostSelector.getSelectedIndex());
    }

    private HostSelectorCombo hostSelector;

    private JButton transfer;

    private JButton upl;

    private JButton down;

    private JButton ssh;

    private JButton sftp;

    private String scriptName = "file_transfer.bsh";

    private void runScript() {
        String sfile = projectInfo.getProjectDirectory()
                + System.getProperty("file.separator") + scriptName;
        if (!new File(sfile).exists())
            return;
        HashMap ma = new HashMap();
        ma.put("document", doc);
        ma.put("projectInfo", projectInfo);
        ScriptUtils.runScript(sfile, ma);
    }

    private void init() {
        setBorder(new TitledBorder("file transfer"));

        logger.debug("at FileTransferPanel.init()");

        hostSelector = new HostSelectorCombo();
        transfer = new JButton("transfer scheme");
        upl = new JButton("upload");
        down = new JButton("download");
        ssh = new JButton("ssh");
        sftp = new JButton("sftp");

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        panel.add(hostSelector);
        panel.add(transfer);
        panel.add(upl);
        panel.add(down);
        panel.add(ssh);
        panel.add(sftp);

        doc = ciss.phase_viewer.jobcontrol.JobController.getJobControlDocument(
                projectInfo, this);
        logger.debug("got document");

        this.runScript();

        hostSelector.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                projectInfo.getChaseFileManager().setHostInfo(
                        hostSelector.getSelectedHost());
                transfer.setEnabled(!hostSelector.getSelectedHost()
                        .isLocalHost());
                upl.setEnabled(!hostSelector.getSelectedHost().isLocalHost());
                down.setEnabled(!hostSelector.getSelectedHost().isLocalHost());
                ssh.setEnabled(!hostSelector.getSelectedHost().isLocalHost());
                sftp.setEnabled(!hostSelector.getSelectedHost().isLocalHost());
                projectInfo.setHostInfo(hostSelector.getSelectedHost());
                saveToDisk();
            }
        });

        transfer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                FileTransferInfoEditorPanel fip = new FileTransferInfoEditorPanel(
                        projectInfo.getChaseFileManager());
            }
        });

        sftp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                SftpClient sfc = new SftpClient(hostSelector.getSelectedHost(),
                        true);
            }
        });

        ssh.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Terminal term = new Terminal(hostSelector.getSelectedHost(),
                        "cd " + projectInfo.getTargetDirectory());
            }
        });

        upl.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (hostSelector.getSelectedHost().isLocalHost()) {
                    logger.info("no need to transfer file for host 'localhost'.");
                    return;
                }
                BatchFileTransferer bft = new BatchFileTransferer(projectInfo,
                        hostSelector.getSelectedHost());
                bft.upload();
            }
        });

        down.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (hostSelector.getSelectedHost().isLocalHost()) {
                    logger.info("no need to transfer file for host 'localhost'.");
                    return;
                }
                BatchFileTransferer bft = new BatchFileTransferer(projectInfo,
                        hostSelector.getSelectedHost());
                bft.download();
            }
        });

        // setLayout(new BorderLayout());
        add(panel, BorderLayout.CENTER);

        hostSelector.setSelectedIndex(hostSelector.getSelectedIndex());
    }

    private void saveToDisk() {
        projectInfo.setTargetDirectory(hostSelector.getSelectedHost());
        Element host = doc.getRootElement().getChild(JobController.JOBCONTROL)
                .getChild(targethost);
        if (host == null) {
            return;
        }

        host.setText(MyElement.encode(hostSelector.getSelectedHost().getName()));
        Element env = host.getChild("env");
        if (env == null || env.getChildren().size() == 0) {
            env = new Element("env");
            host.addContent(env);
        }
        setHostEnvs(env);
        ciss.phase_viewer.jobcontrol.JobController.saveJobControlFile(
                projectInfo.getProjectDirectory(), doc);
    }

    private String targethost = "targethost";

    public boolean readJobControlDocument(Document doc) {
        logger.debug("at readJobControlDocument");

        Element root = doc.getRootElement().getChild(JobController.JOBCONTROL);
        Element elem = root.getChild(targethost);
        if (elem == null) {
            logger.debug("invalid element");
            return false;
        }
        logger.debug("selecting hostSelector");
        hostSelector.setSelectedItem(MyElement.decode(elem.getTextTrim()));
        logger.debug("ok.");
        return true;
    }

    public void initJobControlDocument(Document doc) {
        Element element = new Element(targethost);
        element.setText(hostSelector.getSelectedHost().getName());
        doc.getRootElement().getChild(JobController.JOBCONTROL)
                .addContent(element);

        Element env = new Element("env");
        setHostEnvs(env);
        element.addContent(env);
    }

    private void setHostEnvs(Element env) {
        TaggedString[] hostEnvs = getHostEnvs();
        if (hostEnvs == null || hostEnvs.length == 0) {
            return;
        }

        for (int i = 0; i < hostEnvs.length; i++) {
            Element elem = new Element(hostEnvs[i].getTag());
            elem.setText(MyElement.encode(hostEnvs[i].getValue()));
            java.util.List envList = env.getChildren();
            if (envList == null) {
                env.addContent(elem);
                continue;
            }
            boolean found = false;
            for (int j = 0; j < envList.size(); j++) {
                Element el = (Element) envList.get(j);
                if (el.getName().equals(hostEnvs[i].getTag())) {
                    el.setText(MyElement.encode(hostEnvs[i].getValue()));
                    found = true;
                    break;
                }
            }
            if (!found) {
                env.addContent(elem);
            }
        }
    }

    private TaggedString[] getHostEnvs() {
        Vector vec = new Vector();
        vec.addElement(new TaggedString("targetdir", projectInfo
                .getTargetDirectory()));
        // vec.addElement(new
        // TaggedString("basedir",hosts.getSelectedHost().getProperty("basedir")));
        vec.addElement(new TaggedString("bindir", hostSelector
                .getSelectedHost().getProperty("bindir")));
        vec.addElement(new TaggedString("javadir", hostSelector
                .getSelectedHost().getProperty("javadir")));
        vec.addElement(new TaggedString("mpidir", hostSelector
                .getSelectedHost().getProperty("mpidir")));

        String win = "false";
        if (hostSelector.getSelectedHost().isLocalHost()
                && System.getProperty("os.name").toLowerCase()
                        .startsWith("windows")) {
            win = "true";
        }
        vec.addElement(new TaggedString("windows", win));

        TaggedString[] envs = new TaggedString[vec.size()];
        vec.copyInto(envs);
        return envs;
    }

}
