/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/testsuite/junit/store/org/apache/slide/store/tamino/testtools/sniffer/SnifferAdmin.java,v 1.1 2004/03/25 16:18:15 juergen Exp $
 * $Revision: 1.1 $
 * $Date: 2004/03/25 16:18:15 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.slide.store.tamino.testtools.sniffer;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.SystemColor;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import org.apache.slide.store.tamino.testtools.logger.Logger;

public class SnifferAdmin extends Frame {
    
    private SnifferProxyServer proxy =  new SnifferProxyServer(this, null);
    Toolkit toolkit = getToolkit();
    private int frameWidth  = 400;
    private int frameHeight = 300;
    
    private Logger logger = null;
    
    Panel httpServerPanel = new Panel();
    Label httpHostLabel = new Label();
    Label httpRemotePortLabel = new Label();
    Label httpLocalPortLabel = new Label();
    Label connectedClientsLabel = new Label();
    TextField httpHostField = new TextField();
    TextField httpRemotePortField = new TextField();
    TextField httpLocalPortField = new TextField();
    TextField connectedClientsField = new TextField();
    Button httpStopButton = new Button();
    Button httpStartButton = new Button();
    Checkbox xmlCheck = new Checkbox("xml Output");
    
    boolean httpRunning = false;
    boolean xmlOutput = true;
    
    
    
    private WindowHandler wh = new WindowHandler();
    JLabel fileNameLabel = new JLabel();
    JTextField fileNameTextField = new JTextField();
    JButton snifferStartButton = new JButton();
    JButton snifferStopButton = new JButton();
    JLabel jLabel1 = new JLabel();
    class WindowHandler extends WindowAdapter {
        /********************************************************************************
         ** windowClosing
         ** @pre
         ** @post
         ** @param       e
         ********************************************************************************/
        public void windowClosing(WindowEvent e) {
            handleApplicationClose();
        }
        
    }
    
    public SnifferAdmin(String[] args) {
        try  {
            logger = new Logger(args[0]);
            jbInit();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /********************************************************************************
     ** HTTPProxyAdmin
     ** @pre
     ** @post
     ********************************************************************************/
    public SnifferAdmin() {
        try  {
            logger = new Logger();
            jbInit();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    /********************************************************************************
     ** refresh
     ** @pre
     ** @post
     ** @exception   Exception
     ********************************************************************************/
    protected void refresh() throws Exception {
        connectedClientsField.setText("" + proxy.counterClient);
        show();
    }
    
    /********************************************************************************
     ** jbInit
     ** @pre
     ** @post
     ********************************************************************************/
    private void jbInit() throws Exception {
        
        this.setTitle("Sniffer - All Services Stopped");
        int frameLocationX = (toolkit.getScreenSize().width - frameWidth) / 2;
        int frameLocationY = (toolkit.getScreenSize().height - frameHeight) / 2;
        this.setLocation(frameLocationX, frameLocationY);
        this.setSize(frameWidth, frameHeight);
        this.setResizable(false);
        
        this.eventHandlersSetup();
        
        httpHostLabel.setBounds(new Rectangle(25, 30, 85, 23));
        httpHostLabel.setText("Host:");
        httpRemotePortLabel.setBounds(new Rectangle(25, 60, 85, 23));
        httpRemotePortLabel.setText("Remote Port:");
        httpLocalPortLabel.setBounds(new Rectangle(25, 90, 85, 23));
        httpLocalPortLabel.setText("Local Port:");
        connectedClientsLabel.setBounds(new Rectangle(25, 120, 85, 23));
        connectedClientsLabel.setText("Clients:");
        
        httpHostField.setBounds(new Rectangle(115, 30, 125, 23));
        httpRemotePortField.setBounds(new Rectangle(115, 60, 60, 23));
        httpLocalPortField.setBounds(new Rectangle(115, 90, 60, 23));
        connectedClientsField.setBounds(new Rectangle(115, 120, 60, 23));
        
        httpStartButton.setBounds(new Rectangle(310, 60, 60, 23));
        httpStartButton.setLabel("Begin");
        httpStartButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        httpStart();
                    }});
        
        httpStopButton.setBounds(new Rectangle(310, 90, 60, 23));
        httpStopButton.setLabel("Kill");
        httpStopButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        httpStop();
                    }});
        httpStopButton.setEnabled(false);
        
        httpServerPanel.setLayout(null);
        fileNameLabel.setForeground(Color.black);
        fileNameLabel.setText("File Name :");
        fileNameLabel.setBounds(new Rectangle(24, 196, 72, 15));
        fileNameTextField.setBackground(SystemColor.control);
        fileNameTextField.setOpaque(false);
        fileNameTextField.setBounds(new Rectangle(115, 196, 164, 24));
        snifferStartButton.setText("Start");
        snifferStartButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        snifferStart(fileNameTextField.getText().trim());
                    }
                });
        snifferStartButton.setBounds(new Rectangle(311, 195, 63, 23));
        snifferStopButton.setText("Stop");
        snifferStopButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        snifferStop(fileNameTextField.getText().trim());
                    }
                });
        snifferStopButton.setBounds(new Rectangle(311, 230, 64, 24));
        snifferStopButton.setEnabled(false);
        jLabel1.setToolTipText("");
        jLabel1.setText("Sniffer Console");
        jLabel1.setBounds(new Rectangle(164, 169, 93, 19));
        
        xmlCheck.setEnabled(true);
        xmlCheck.setState(true);
        xmlCheck.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e)
            {
                setXMLOutput(!xmlCheck.getState());
            }
            
            public void mousePressed(MouseEvent e){}
            public void mouseEntered(MouseEvent e){}
            public void mouseReleased(MouseEvent e){}
            public void mouseExited(MouseEvent e){}
        });
        xmlCheck.setBounds(new Rectangle(25, 169, 93, 19));
        
        this.add(httpServerPanel, BorderLayout.CENTER);
        httpServerPanel.add(httpHostLabel, null);
        httpServerPanel.add(httpRemotePortLabel, null);
        httpServerPanel.add(httpLocalPortLabel, null);
        httpServerPanel.add(connectedClientsLabel, null);
        httpServerPanel.add(httpHostField, null);
        httpServerPanel.add(httpLocalPortField, null);
        httpServerPanel.add(httpRemotePortField, null);
        httpServerPanel.add(connectedClientsField, null);
        httpServerPanel.add(httpStopButton, null);
        httpServerPanel.add(httpStartButton,null);
        httpServerPanel.add(fileNameLabel, null);
        httpServerPanel.add(snifferStartButton, null);
        httpServerPanel.add(snifferStopButton, null);
        httpServerPanel.add(fileNameTextField, null);
        httpServerPanel.add(xmlCheck,null);
        httpServerPanel.add(jLabel1, null);
        
        httpHostField.setText(proxy.host);
        httpRemotePortField.setText("" + proxy.remoteport);
        httpLocalPortField.setText("" + proxy.localport);
        connectedClientsField.setText("" + proxy.counterClient);
        fileNameTextField.setText(""+proxy.fileName);
    }
    
    
    
    
    /********************************************************************************
     ** httpStart
     ** @pre
     ** @post
     ********************************************************************************/
    protected void httpStart() {
        if (httpRunning) return;
        httpRunning = true;
        
        //
        // Future Feature:
        //
        // Should do some error checking here for valid data in text fields
        //
        // Host         ->  int.int.int.int
        // Local Host   ->  int
        // Remote Host  ->  int
        //
        
        this.setTitle("Sniffer - Running");
        
        xmlCheck.setEnabled(false);
        httpHostField.setEditable(false);
        httpRemotePortField.setEditable(false);
        httpLocalPortField.setEditable(false);
        httpStartButton.setEnabled(false);
        httpStopButton.setEnabled(true);
        // DO your stuff Here
        
        if (fileNameTextField.getText().length() > 0)
        {
            try
            {
                //logger.setOutput(xmlOutput);
                logger.startLogger(fileNameTextField.getText().trim());
                snifferStartButton.setEnabled(false);
                snifferStopButton.setEnabled(true);
                
            }
            catch (IOException ioe)
            {
                ioe.printStackTrace();
                snifferStartButton.setEnabled(true);
                snifferStopButton.setEnabled(false);
                xmlCheck.setEnabled(true);
            }
        }
        
        try{
            proxy = null;
            proxy =  new SnifferProxyServer(this,httpHostField.getText(),
                                            Integer.parseInt(httpRemotePortField.getText().trim()),
                                            Integer.parseInt(httpLocalPortField.getText().trim()),logger,fileNameTextField.getText());
            
        }catch(Exception e){
            httpStop();
            return;
        }
        proxy.start();
    }
    
    
    /********************************************************************************
     ** httpStop
     ** @pre
     ** @post
     ********************************************************************************/
    protected void httpStop() {
        if (!httpRunning) return;
        httpRunning = false;
        
        this.setTitle("Sniffer - Stopped");
        
        httpHostField.setEditable(true);
        httpRemotePortField.setEditable(true);
        httpLocalPortField.setEditable(true);
        
        httpStartButton.setEnabled(true);
        httpStopButton.setEnabled(false);
        xmlCheck.setEnabled(true);
        
        // DO your stuff Here
        if ( proxy.isAlive() )
            proxy.shutdown();
    }
    
    
    /********************************************************************************
     ** eventHandlersSetup
     ** @pre
     ** @post
     ********************************************************************************/
    private void eventHandlersSetup() {
        this.addWindowListener(wh);
    }
    
    
    /********************************************************************************
     ** handleApplicationClose
     ** @pre
     ** @post
     ********************************************************************************/
    private void handleApplicationClose() {
        httpStop();
        this.dispose();
        System.exit(0);
    }
    
    
    
    /********************************************************************************
     ** main
     ** @pre
     ** @post
     ** @param       args
     ********************************************************************************/
    public static void main(String[] args) {
        SnifferAdmin admin;
        if (args.length < 1)
        {
            admin = new SnifferAdmin();
        }
        else
        {
            admin = new SnifferAdmin(args);
        }
        admin.show();
    }
    
    
    private void snifferStop(String path)
    {
        try
        {
            if (!(logger == null))
            {
                logger.stopLogger();
                snifferStopButton.setEnabled(false);
                snifferStartButton.setEnabled(true);
                fileNameTextField.setEditable(true);
                xmlCheck.setEnabled(true);
            }
            else
            {
                System.out.println ("Sniffer - Error : Make sure Sniffer is running ");
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        
    }
    
    private void snifferStart(String path)
    {
        if (!(logger == null) && (!(fileNameTextField.getText().length() == 0)))
        {
            try
            {
                logger.startLogger(fileNameTextField.getText().trim());
                snifferStartButton.setEnabled(false);
                snifferStopButton.setEnabled(true);
                fileNameTextField.setEditable(false);
                xmlCheck.setEnabled(false);
            }
            catch (IOException ioe)
            {
                ioe.printStackTrace();
                snifferStartButton.setEnabled(true);
                snifferStopButton.setEnabled(false);
                fileNameTextField.setEditable(true);
                xmlCheck.setEnabled(true);
            }
        }
        else
        {
            if (logger == null)
            {
                System.out.println ("Sniffer - Error : Make sure Sniffer is running ");
            }
            else
            {
                System.out.println("Sniffer - Error : No File Name Supplied");
            }
        }
    }

    /**
     * Set a switch in Logger weather the output is in XML format or not
     *
     * @pre         state = true or false
     *
     * @param       state       print XML format (true) or direct to file (false)
     **/
    public void setXMLOutput(boolean state)
    {
        logger.setOutput(state);
    }
    
}
