package net.kldp.logviewer.work;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import net.kldp.logviewer.View;
import net.kldp.logviewer.common.log.LogViews;
import net.kldp.logviewer.model.LogViewerEntry;

import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TelnetNotificationHandler;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
import org.apache.log4j.Logger;

public class WorkerTelnetTail extends Thread implements Tail, TelnetNotificationHandler {
	private static final Logger logger = LogViews.getLogger(WorkerFileTail.class);
	
	View view = null;
	LogViewerEntry viewEntry = null;
	private volatile boolean shutdownThread = false;
	private volatile boolean sleepThread = false;
	
	static TelnetClient tc = null;
    
//    static String REQ_IP 	= "218.50.181.37";
//    static String REQ_PORT 	= "23";
    
//    static String REQ_ID 	= "ux-muse-1\r\n";
//    static String REQ_PASS	= "musmidcktf01\r\n";
    
//    static String FIRST_MSG = "cd t-uapl-05\r\n";
//    static String TARGET_DIR = "cd logs\r\n";
//    static String TARGET_FILE = "tail -f muse.log\r\n";
	
     /***
     * Main for the TelnetClientExample.
     ***/
    public static void main(String[] args) throws IOException
    {
    	
    	LogViewerEntry viewEntry = new LogViewerEntry();
    	viewEntry.setDelaySecond(1000);
    	
        FileOutputStream fout = null;

        String remoteip = "218.50.181.37";
        int remoteport = 23;

        try {
            fout = new FileOutputStream ("spy.log", true);
        } catch (Exception e) {
            System.err.println("Exception while opening the spy file: " + e.getMessage());
        }

        tc = new TelnetClient();

        TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
        EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
        SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);

        try {
            tc.addOptionHandler(ttopt);
            tc.addOptionHandler(echoopt);
            tc.addOptionHandler(gaopt);
        }
        catch (InvalidTelnetOptionException e)
        {
            System.err.println("Error registering option handlers: " + e.getMessage());
        }

        while (true)
        {
            try
            {
                tc.connect(remoteip, remoteport);

                WorkerTelnetTail telnetTail = new WorkerTelnetTail();
//                Thread reader = new Thread ();
                tc.registerNotifHandler(telnetTail);
                telnetTail.start();
                
                System.out.println("메몰ㅇ'''''''''''''''''''''''''''''");
            
//                reader.start();
                OutputStream outstr = tc.getOutputStream();

                byte[] buff = new byte[1024];
                int ret_read = 0;
                
                try {
                	Thread.sleep(2000);
                	
                	//System.out.println("---------------------[1]");
                    outstr.write(new String("telnet\r\n").getBytes(), 0 , new String("telnet\r\n").getBytes().length);
                    outstr.flush();
                    Thread.sleep(3000);
                    
                    //System.out.println("---------------------[2]");
                    outstr.write(new String("paul\r\n").getBytes(), 0 , new String("paul\r\n").getBytes().length);
                    outstr.flush();
                    Thread.sleep(3000);
                    
                    //System.out.println("---------------------[3]");
                    outstr.write(new String("dir\r\n").getBytes(), 0 , new String("dir\r\n").getBytes().length);
                    outstr.flush();
                } catch (Exception e) {
                //	end_loop = true;
                }
                
                Thread.sleep(10000000);

                try
                {
                    tc.disconnect();
                }
                catch (Exception e)
                {
                          System.err.println("Exception while connecting:" + e.getMessage());
                }
            }
            catch (Exception e)
            {
                    System.err.println("Exception while connecting:" + e.getMessage());
                    System.exit(1);
            }
        }
    }
    
    public WorkerTelnetTail() {
    	
    }
    
	public WorkerTelnetTail(LogViewerEntry viewEntry, View tailMe) {
		if(logger.isDebugEnabled()) { 
			logger.debug("WorkerTelnetTail Started......[name]" + viewEntry.getName());
		}
		this.view = tailMe;
		
		outputLog(viewEntry.getRealPath() + "의 보기를 시작합니다.\r\n");		
		this.viewEntry = viewEntry;
		
		
	}
	
	/**
	 * 잠시중단
	 */
	public void sleep() {
		sleepThread = true;
		
		try {
			Thread.currentThread().wait();
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 다시시작
	 */
	public void reStart() {
		sleepThread = false;		
		
		Thread.currentThread().notify();
	}
	
	/**
	 * 쓰레드 종료
	 *
	 */
	public void shutdown() {
		shutdownThread = true;
		interrupt();
	}
	
	 /***
     * Callback method called when TelnetClient receives an option
     * negotiation command.
     * <p>
     * @param negotiation_code - type of negotiation command received
     * (RECEIVED_DO, RECEIVED_DONT, RECEIVED_WILL, RECEIVED_WONT)
     * <p>
     * @param option_code - code of the option negotiated
     * <p>
     ***/
    public void receivedNegotiation(int negotiation_code, int option_code)  {
        String command = null;
        if(negotiation_code == TelnetNotificationHandler.RECEIVED_DO) {
            command = "DO";
        } else if(negotiation_code == TelnetNotificationHandler.RECEIVED_DONT) {
            command = "DONT";
        } else if(negotiation_code == TelnetNotificationHandler.RECEIVED_WILL) {
            command = "WILL";
        } else if(negotiation_code == TelnetNotificationHandler.RECEIVED_WONT) {
            command = "WONT";
        }
        
        System.out.println("Received " + command + " for option code " + option_code);
   }

    /***
     * Reader thread.
     * Reads lines from the TelnetClient and echoes them
     * on the screen.
     ***/
    public void run() {
    	// 기본 연결 및 기본 명령 부분으로 이동한다.
    	
        InputStream instr = tc.getInputStream();
		
        byte[] buff = new byte[1024];
        int ret_read = 0;
            
    	try {
    	    while(!shutdownThread) {
    	    	
    	    	try {
    	    		// thread의 wait 상태이다.
    				if(sleepThread) {
    					
    				// working 상태
    				} else {
    					// Telnet작업을 계속한다
				     
				        ret_read = instr.read(buff);
				        if(ret_read > 0) {
				        	System.out.print(new String(buff, 0, ret_read));
				        }
				     
//					    // 원하는 시간만큼 딜레이 된다. 
//				    	try {
//				    		Thread.sleep(viewEntry.getDelaySecond() * 1000);
//				    	} catch(InterruptedException e) {}
					}
		    	} catch (Exception e) {
		    		e.printStackTrace();
		    		outputLog(e.getMessage());
		    	}
		    }
		} catch (Exception e) {
			e.printStackTrace();
			
			outputLog(e.getMessage());					
		} finally {		
			 try {
	            tc.disconnect();
	        } catch (Exception e) {
	            System.err.println("Exception while closing telnet:" + e.getMessage());
	        }
		        
			logger.debug("###[WorkerFileTail가 쓰레드 작업종료] " + Thread.currentThread().getId());
		}
    }

	/**
	 * 화면에 출력하기 위해 work에게 던져주는 역활을 한다.
	 * 
	 * @param data
	 */
	protected void outputLog(byte[] data) {
		if(!new String(data).equals("")) view.fileAddData(new String(data));
	}
	
	protected void outputLog(String data) {
		System.out.println("[data]" + data);
//		if(!"".equals(data)) view.fileAddData(data);
	}
}
