/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/testsuite/junit/store/org/apache/slide/store/tamino/testtools/sniffer/SnifferProxyClient.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.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import org.apache.slide.store.tamino.testtools.logger.Logger;

public class SnifferProxyClient{
    private Socket socket = null;
    //InputStream from the the client
    private InputStream from_client;
    //OutputStream to the client
    private OutputStream to_client;
    //InputStream from the server
    private InputStream from_server;
    //OutputStream from the server
    private OutputStream to_server;
    //Server name
    private String host;
    //Server Port
    private int remoteport;
    //Logger
    private Logger LOGGER;
    
    
    /********************************************************************************
     ** HTTPProxyClient
     ** @pre
     ** @post
     ** @param       in
     ** @param       out
     ** @param       socket
     ** @param       host
     ** @param       remoteport
     ********************************************************************************/
    public SnifferProxyClient(InputStream in, OutputStream out, Socket socket, String host, int remoteport, boolean fileOpen, Logger logger  ) {
        this.host = host;
        this.remoteport = remoteport;
        from_client = in;
        to_client = out;
        this.socket = socket;
        this.LOGGER = logger;
        
    }
    
    
    /********************************************************************************
     ** job
     ** @pre
     ** @post
     ********************************************************************************/
    public void job(){
        boolean bRun = true;
        Socket server;
        try {
            server = new Socket(host, remoteport);
            from_server = server.getInputStream();
            to_server = server.getOutputStream();
        }
        catch (Exception e) {
            try{
                e.printStackTrace();
                PrintWriter pw = new PrintWriter(new OutputStreamWriter(to_client));
                pw.println("HTTPProxyClient could not connect to " + host + ":" + remoteport);
                pw.flush();
            }
            catch(Exception er){}
            close();
            return;
        }
        
        Thread isp = new Thread() {
            
            public void run() {
                try
                {
                    byte[] buffer = new byte[2048];
                    int bytes_read = 0;
                    outputLogger("response");
                    //System.out.println("@@response@@");
                    
                    while ((bytes_read = from_server.read(buffer)) != -1)
                    {
                        //Write the buffer to the client
                        to_client.write(buffer,0,bytes_read);
                        //outputLogger(convert.getBytes("UTF8"),convert.getBytes("UTF8").length);
                        outputLogger(buffer,bytes_read);
                        to_client.flush();
                        
                        bytes_read = 0;
                        buffer = new byte[2048];
                    }
                }
                catch (Exception e) {}
                close();
                
            }
        };
        // ************************************* RESPONSE ****************************************************
        // ********************************** END OF THREAD **************************************************
        
        if(bRun) {
            bRun = false;
            try {
                //isp.setPriority(isp.MIN_PRIORITY);
                isp.start(); //WHY IS THIS REQUIRED HERE?!!
                int bytes_read = 0;
                byte[] buffer = new byte[2048];
                
                outputLogger("step");
                outputLogger("request");
                //System.out.println("@@request@@");
                synchronized(isp)
                {
                    while ((bytes_read = from_client.read(buffer)) != -1)
                    {
                        //System.out.println(new String(buffer));
                        String convert = new String(buffer);
                        //System.out.println(new String(convert.getBytes("UTF8")));
                        to_server.write(buffer,0,bytes_read);
                        to_server.flush();
                        outputLogger(convert.getBytes("UTF8"),convert.getBytes("UTF8").length);
                        //System.out.println(new String(buffer));
                        bytes_read = 0;
                        buffer = new byte[2048];
                    }
                }
            } //END bytes.read while loop
            catch (Exception e) {} //Change back to IOException
            close();
        }
    }
    
    private boolean containsBinaryData ( String s ) {
        for ( int i = 0; i < s.length(); i++ ) {
            if ( ! Character.isDefined( s.charAt(i) ) ) {
                return true;
            }
        }
        return false;
    }
    
    /********************************************************************************
     ** close
     ** @pre
     ** @post
     ********************************************************************************/
    private void close(){
        try { to_client.close(); } catch (Exception e) {}
        try { to_server.close(); } catch (Exception e) {}
        try { from_client.close(); } catch (Exception ex) {}
        try { from_server.close(); } catch (Exception ex) {}
        try { socket.close(); } catch (Exception ex) {}
    }
    
    /**
     * Output to the Logger the byte[] and which elementName it is part of
     * @param     byte[]
     * @param     int
     * @param     String
     */
    private synchronized void outputLogger(byte[] buffer, int size)
    {
        LOGGER.outputBuffer(buffer,size);
    }
    
    /**
     * Output just a elementName to the logger
     * @param     String
     */
    private synchronized void outputLogger(String elementName)
    {
        elementName = "\n\n@@"+elementName+"@@\n\n";
        LOGGER.outputBuffer(elementName.getBytes(),elementName.getBytes().length);
    }
}
