/*
 *  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.ajp.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.apache.ajp.Ajp13;
import org.apache.ajp.Ajp13Packet;
import org.apache.ajp.RequestHandler;
import org.apache.tomcat.util.http.BaseRequest;
import org.apache.tomcat.util.http.MimeHeaders;

public class TestAjp13 extends TestCase {

    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog( TestAjp13.class );

    Ajp13Server server = null;

    public TestAjp13(String name) {
        super(name);
    }

    public static Test suite() {
        return new TestSuite(TestAjp13.class);
    }

    protected void setUp() {
        println("setup...");

        server = new Ajp13Server();
        server.start();
    }

    protected void tearDown() {
        println("tear down...");

        server.shutdown();
    }

    public void test1() throws Exception {
        println("running test1");

        Socket s = new Socket("localhost", 8009);

        Ajp13Packet p = new Ajp13Packet(Ajp13.MAX_PACKET_SIZE);
        p.appendInt(0x1234);
        p.appendInt(0);
        p.setByteOff(4);
        p.appendByte(RequestHandler.JK_AJP13_FORWARD_REQUEST);
        p.appendByte((byte)2);
        p.appendString("http");
        p.appendString("/test_uri");
        p.appendString("remote_addr");
        p.appendString("remote_host");
        p.appendString("server_name");
        p.appendInt(80);
        p.appendBool(false);
        p.appendInt(3);
        p.appendString("my header");
        p.appendString("my header value");
        p.appendInt((0xA0 << 8) + RequestHandler.SC_REQ_AUTHORIZATION);
        p.appendString("some auth string");
        p.appendInt((0xA0 << 8) + RequestHandler.SC_REQ_USER_AGENT);
        p.appendString("TestAjp13 User Agent");
        p.appendByte(RequestHandler.SC_A_ARE_DONE);

        int len = p.getByteOff() - 4;
        p.setByteOff(2);
        p.appendInt(len);

        OutputStream os = s.getOutputStream();
        os.write(p.getBuff(), 0, len + 4);

        InputStream is = s.getInputStream();

        println("decoding response...");
        
        boolean done = false;
        while (!done) {
            int b1, b2;
            // read a packet

            // first 2 bytes should be AB
            b1 = is.read();
            assertTrue("byte 1 was " + (char)b1, b1 == (int)'A');
            b2 = is.read();
            assertTrue("byte 2 was " + (char)b2, b2 == (int)'B');

            println("b1 = " + (char)b1 + "; b2 = " + (char)b2);
            
            // next is length
            b1 = is.read();
            b1 &= 0xFF;
            b2 = is.read();
            b2 &= 0xFF;
            
            int l = (b1 << 8) + b2;

            println("length = " + l);

            // now get data
            byte[] buf = new byte[l];
            int n = 0;
            int off = 0;
            int total = 0;
            while ((n = is.read(buf, off, l - off)) != -1 && (l - off != 0)) {
                total += n;
                off += n;
            }

            println("read " + total);

            assertTrue("total read was " + total +
                       ", should have been " + l,
                       total == l);

            

            int code = (int)buf[0];

            switch (code) {
            case 3:
                println("AJP13_SEND_BODY_CHUNK ");
                break;
            case 4:
                println("AJP13_SEND_HEADERS ");
                break;
            case 5:
                println("AJP13_END_RESPONSE ");
                done = true;
                break;
            case 6:
                println("AJP13_GET_BODY_CHUNK ");
                break;
            default:
                assertTrue("invalid prefix code:  " + code, false);
                break;
            }
        }

        println("shutting down socket...");
        s.shutdownOutput();
        s.shutdownInput();
        s.close();

        println("done test1...");
    }

    protected static void println(String msg) {
        if (log.isDebugEnabled())
            log.debug("[TestAjp13] " + msg);
    }

    public static void main(String[] args) throws Exception {
    }
}


class Ajp13Server extends Thread {

    boolean shutdown = false;

    void shutdown() {
        this.shutdown = true;
        this.interrupt();
    }

    public void run() {
        try {
            ServerSocket server = new ServerSocket(8009);
            TestAjp13.println("Ajp13Server running...");
            Socket socket = server.accept();
            Ajp13 ajp13 = new Ajp13();
            MimeHeaders headers = new MimeHeaders();
            BaseRequest request = new BaseRequest();
            ajp13.setSocket(socket);

            boolean moreRequests = true;
            while (moreRequests && !shutdown) {
            
                int status = 0;
                try {
                    status = ajp13.receiveNextRequest(request);
                } catch (IOException e) {
                    if (shutdown) {
                        TestAjp13.println("Ajp13Server told to shutdown");
                        break;
                    }
                    TestAjp13.println("process: ajp13.receiveNextRequest -> " + e);
                }
            
                if( status==-2) {
                    // special case - shutdown
                    // XXX need better communication, refactor it
                    //                  if( !doShutdown(socket.getLocalAddress(),
                    //                                  socket.getInetAddress())) {
                    //                      moreRequests = false;
                    //                      continue;
                    //                  }
                    break;
                }
            
            	// Special low level request allready handled (ie: PING/PONG)
            	if( status == 999 )
            	{
					request.recycle();
            		continue;
            	}
            	
                if( status != 200 )
                    break;

                TestAjp13.println(request.toString());

                String message =
                    "<html><body><pre>" +
                    "hello from ajp13:  " +
                    System.getProperty("line.separator") +
                    request.toString() +
                    "</pre></body></html>";

                headers.addValue("content-type").setString( "text/html");
                headers.addValue("content-length").setInt(message.length());
                headers.addValue("my-header").setString( "my value");
                ajp13.sendHeaders(200, headers);

                byte[] b = message.getBytes();
                ajp13.doWrite(b, 0, b.length);

                ajp13.finish();

                request.recycle();
                headers.recycle();
            }

            try {
                ajp13.close();
            } catch (IOException e) {
                TestAjp13.println("process: ajp13.close ->" + e);
            }

            try {
                socket.close();
            } catch (IOException e) {
                TestAjp13.println("process: socket.close ->" + e);
            }
            socket = null;

            TestAjp13.println("process:  done");

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.toString());
        }
    }
}

