/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/11/22 10:25:45
!  AUTHOR(S): KOGA, Junichiro
!  File : SimpleRefreshableMonitor.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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JTextArea;

import org.apache.log4j.Logger;

import ciss.phase_viewer.common.Utils;
import ciss.phase_viewer.jobcontrol.MonitorPanelInterface;
import ciss.phase_viewer.projectbrowser.ProjectInfo;
import ciss.phase_viewer.ssh.RemoteStdOut;
import ciss.phase_viewer.ssh.filechooser.RemoteFile;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.Session;

/**
 * 'cat fileName'の出力をリフレッシュしながら表示する. jobstatusファイルに利用.
 * 
 * @author KOGA, Junichiro
 * 
 */
public abstract class SimpleRefreshableMonitor implements Monitorable {
    private Logger logger = Logger.getLogger(SimpleRefreshableMonitor.class
            .getName());

    protected ProjectInfo projectInfo;

    protected Session session;
    protected JTextArea textArea;

    protected RemoteStdOut remoteStdOut;

    private javax.swing.Timer timer;
    private File mostRescent;

    protected int REFRESH = 100; /* リフレッシュレート, in milisecs. 変更したい場合サブクラスで定義しなおす. */

    private long lastMod = -1L;

    public SimpleRefreshableMonitor(ProjectInfo projectInfo) {
        this.projectInfo = projectInfo;
    }

    /**
     * このような場合, グラフは不要であろうから空実装.
     */
    public void createGraphFrom(JTextArea textArea) {
    }

    /**
     * このような場合, グラフは不要であろうから空実装.
     */
    public void destroyGraph() {
    }

    public boolean isGraphCreatable(JTextArea textArea) {
        return false;
    }

    public boolean isMonitorable() {
        return true;
    }

    protected abstract String getFileToMonitor();

    public void monitor(Session session, JTextArea textArea) {
        this.session = session;
        this.textArea = textArea;
        preProcess();
        timer = new javax.swing.Timer(REFRESH, new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                doIt();
            }
        });
        timer.start();
    }

    private boolean firstTime = true;

    private void doIt() {
        if (firstTime || mostRescent.lastModified() > lastMod) {
            firstTime = false;
            remoteStdOut.doIt();
        }
    }

    private void preProcess() {
        String nam = getFileToMonitor();
        try {
            ChannelSftp c = null;
            if (session != null) {
                Channel channel = session.openChannel("sftp");
                channel.connect();
                c = (ChannelSftp) channel;
            }
            RemoteFile rf = new RemoteFile(projectInfo.getTargetDirectory(), c);
            File[] files = rf.listFiles();
            if (files == null || files.length == 0) {
                // logger.warn("no files!");
                return;
            }
            for (int i = 0; i < files.length; i++) {
                if (files[i].getName().matches(nam)) {
                    if (lastMod < files[i].lastModified()) {
                        mostRescent = files[i];
                        lastMod = files[i].lastModified();
                    }
                }
            }
        } catch (Exception exc) {
            logger.error("failed to get remote-host info.");
            exc.printStackTrace();
            return;
        }
        String fs = "/";
        if (mostRescent == null) {
            logger.warn("no matching file.");
            return;
        }
        String cat = "cat ";
        String dir = projectInfo.getTargetDirectory();
        if (session == null) {
            fs = System.getProperty("file.separator");
            if (System.getProperty("os.name").toLowerCase()
                    .startsWith("windows")) {
                cat = "cat.exe ";
            }
            dir = projectInfo.getProjectDirectory();
        }
        if (!dir.endsWith(fs)) {
            dir += fs;
        }
        String fname = Utils.getPathDQ(dir + mostRescent.getName());
        String command = cat + fname;
        logger.debug("command: " + command);

        remoteStdOut = new RemoteStdOut(session, command, textArea);
        remoteStdOut.setMode(RemoteStdOut.REPLACE);
    }

    public void stopMonitor() {
        if (remoteStdOut != null) {
            remoteStdOut.terminate();
        }
        timer.stop();
        firstTime = true;
    }

    private MonitorPanelInterface monitorPanel;

    /*
     * (non-Javadoc)
     * 
     * @see
     * ciss.phase_viewer.file.Monitorable#setMonitorPanel(ciss.phase_viewer.
     * jobcontrol.MonitorPanel)
     */
    public void setMonitorPanel(MonitorPanelInterface monitorPanel) {
        this.monitorPanel = monitorPanel;
    }

}
