/*
 */
package org.apache.tomcat.lite.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;

import junit.framework.TestCase;

import org.apache.tomcat.lite.TestMain;
import org.apache.tomcat.lite.http.HttpConnectionPool.RemoteServer;
import org.apache.tomcat.lite.io.IOBuffer;
import org.apache.tomcat.lite.io.SocketConnector;

public class SpdyTest extends TestCase {
    HttpConnector http11Con = TestMain.shared().getClient();

    static HttpConnector spdyCon = HttpClient.newClient();

    static HttpConnector spdyConSsl = HttpClient.newClient();

    HttpConnector memSpdyCon = new HttpConnector(null);

    public void testClient() throws IOException {
        HttpRequest req =
            spdyCon.request("http://localhost:8802/echo/test1");

        // Force SPDY - no negotiation
        req.setProtocol("SPDY/1.0");

        HttpResponse res = req.waitResponse();

        assertEquals(200, res.getStatus());
        //assertEquals("", res.getHeader(""));

        BufferedReader reader = res.getReader();
        String line1 = reader.readLine();
        //assertEquals("", line1);
    }

    public void testSslClient() throws IOException {

        HttpRequest req =
            spdyConSsl.request("http://localhost:8443/echo/test1");
        // Enable SSL for the connection.
        // TODO: this must be done on the first request, all will be
        // encrypted.
        req.setSecure(true);
        // Force SPDY - no negotiation
        req.setProtocol("SPDY/1.0");

        HttpResponse res = req.waitResponse();

        assertEquals(200, res.getStatus());
        //assertEquals("", res.getHeader(""));

        res.setReadTimeout(2000);
        BufferedReader reader = res.getReader();
        String line1 = reader.readLine();
        //assertEquals("", line1);
    }


    // Initial frame generated by Chrome
    public void testParse() throws IOException {
            InputStream is =
            getClass().getClassLoader().getResourceAsStream("org/apache/tomcat/lite/http/spdyreq0.bin");

        IOBuffer iob = new IOBuffer();
        iob.append(is);

        SpdyConnection con = new SpdyConnection(memSpdyCon, new RemoteServer());

        // By default it has a dispatcher buit-in
        con.serverMode = true;

        con.dataReceived(iob);

        HttpChannel spdyChannel = con.channels.get(1);

        assertEquals(1, con.lastFrame.version);
        assertEquals(1, con.lastFrame.type);
        assertEquals(1, con.lastFrame.flags);

        assertEquals(417, con.lastFrame.length);

        // TODO: test req, headers
        HttpRequest req = spdyChannel.getRequest();
        assertTrue(req.getHeader("accept").indexOf("application/xml") >= 0);

    }

    // Initial frame generated by Chrome
    public void testParseCompressed() throws IOException {
        InputStream is =
            getClass().getClassLoader().getResourceAsStream("org/apache/tomcat/lite/http/spdyreqCompressed.bin");

        IOBuffer iob = new IOBuffer();
        iob.append(is);

        SpdyConnection con = new SpdyConnection(memSpdyCon, new RemoteServer());

        // By default it has a dispatcher buit-in
        con.serverMode = true;

        con.dataReceived(iob);

        HttpChannel spdyChannel = con.channels.get(1);

        assertEquals(1, con.lastFrame.version);
        assertEquals(1, con.lastFrame.type);
        assertEquals(1, con.lastFrame.flags);

        // TODO: test req, headers
        HttpRequest req = spdyChannel.getRequest();
        assertTrue(req.getHeader("accept").indexOf("application/xml") >= 0);

    }

    // Does int parsing works ?
    public void testLargeInt() throws Exception {

        IOBuffer iob = new IOBuffer();
        iob.append(0x80);
        iob.append(0x01);
        iob.append(0xFF);
        iob.append(0xFF);

        iob.append(0xFF);
        iob.append(0xFF);
        iob.append(0xFF);
        iob.append(0xFF);

        SpdyConnection con = new SpdyConnection(memSpdyCon, new RemoteServer());
        con.dataReceived(iob);
        assertEquals(1, con.currentInFrame.version);
        assertEquals(0xFFFF, con.currentInFrame.type);
        assertEquals(0xFF, con.currentInFrame.flags);
        assertEquals(0xFFFFFF, con.currentInFrame.length);

    }

    // Does int parsing works ?
    public void testBad() throws Exception {

            IOBuffer iob = new IOBuffer();
            iob.append(0xFF);
            iob.append(0xFF);
            iob.append(0xFF);
            iob.append(0xFF);

            iob.append(0xFF);
            iob.append(0xFF);
            iob.append(0xFF);
            iob.append(0xFF);

            SpdyConnection con = new SpdyConnection(memSpdyCon, new RemoteServer());
            con.dataReceived(iob);

            assertEquals(1, con.streamErrors.get());

    }

}
