/**
 * @file RTSPRequest.cpp
 *
 */

#define DBG_LEVEL 3
#include <Raym/Log.h>
#include "net/RTSPRequest.h"

using namespace Raym;

namespace NET
{

RTSPRequest::RTSPRequest()
{
}

RTSPRequest::~RTSPRequest()
{
}

RTSPRequest *RTSPRequest::requestWithSocket(SOCKET sock)
{
    DebugLog2("%s", __FUNCTION__);

    char buf[16384];
    int offset = 0;
    while (offset < sizeof(buf) - 1)
    {
        int len = recv(sock, &buf[offset], 1, 0);
        if (len == 0)
        {
            break;
        }
        if (offset > 0)
        {
            if ((buf[offset - 1] == '\r') && (buf[offset] == '\n'))
            {
                ++offset;
                break;
            }
        }
        ++offset;
    }
    buf[offset] = '\0';

    DebugLog2("request line: %s", buf);

    RTSPRequest *result = NULL;

    String *method  = NULL;
    String *uri     = NULL;
    String *version = NULL;
    if (strchr(buf, ' ') != NULL)
    {
        char *p = strchr(buf, ' ');
        *p++ = '\0';
        if ((buf[strlen(buf) - 2] == '\r') && (buf[strlen(buf) - 1] == '\n'))
        {
            buf[strlen(buf) - 2] = '\0';
        }
        method = String::alloc()->initWithUTF8String(&buf[0]);
        while (*p == ' ')
        {
            ++p;
        }
        if (strchr(p, ' ') != NULL)
        {
            char *p2 = strchr(p, ' ');
            *p2++ = '\0';
            if ((p[strlen(p) - 2] == '\r') && (p[strlen(p) - 1] == '\n'))
            {
                p[strlen(p) - 2] = '\0';
            }
            uri = String::alloc()->initWithUTF8String(p);
            while (*p2 == ' ')
            {
                ++p2;
            }
            if (strchr(p2, ' ') == NULL)
            {
                if ((p2[strlen(p2) - 2] == '\r') && (p2[strlen(p2) - 1] == '\n'))
                {
                    p2[strlen(p2) - 2] = '\0';
                }
                version = String::alloc()->initWithUTF8String(p2);
            }
        }
    }

    if (method != NULL)
    {
        DebugLog3("method: %s", method->cString());
    }
    if (uri != NULL)
    {
        DebugLog3("uri: %s", uri->cString());
    }
    if (version != NULL)
    {
        DebugLog3("version: %s", version->cString());
    }

    if (version != NULL)
    {
        if (version->isMatch("^(HTTP/1.[01]|RTSP/1.0)$"))
        {
            InternetTextMessageHeader *header = InternetTextMessageHeader::alloc()->initWithSocket(sock);
            if (header != NULL)
            {
                InternetTextMessageBody *body = NULL;
                /*
                if (header->fieldBodyForName("Transfer-Encoding") != NULL)
                {
                    DebugLog3("has Transfer-Encoding\n");
                    abort();
                }
                else if (header->fieldBodyForName("Content-Length") != NULL)
                {
                    DebugLog3("has Content-Length\n");
                    abort();
                }
                else if (header->fieldBodyForName("Content-Type") != NULL)
                {
                    DebugLog3("has Content-Type\n");
                    abort();
                }
                */

                InternetTextMessage *message = InternetTextMessage::alloc()->initWithHeaderAndBody(header, body);
                RELEASE(header);
                RELEASE(body);

                result = new RTSPRequest();
                result->setMethod(method);
                result->setURI(uri);
                result->setVersion(version);
                result->setMessage(message);
                result->autorelease();

                RELEASE(message);
            }
            else
            {
                DebugLog3("error: InternetTextMessageHeader::headerWithSocket()\n");
            }
        }
    }

    RELEASE(method);
    RELEASE(uri);
    RELEASE(version);

    return result;
}

const char *RTSPRequest::className()
{
    return "RTSPRequest";
}

} // NET
