/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 PacketVideo
 *
 * 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.
 * -------------------------------------------------------------------
 */
#ifndef HTTP_PARSER_INTERNAL_H_
#define HTTP_PARSER_INTERNAL_H_

#include "oscl_refcounter_memfrag.h"
#include "oscl_vector.h"
#include "http_parcom_internal.h"
#include "http_parser_external.h"

#ifndef PVMF_POOL_BUFFER_ALLOCATOR_H_INCLUDED
#include "pvmf_pool_buffer_allocator.h"
#endif

#ifndef PVLOGGER_H_INCLUDED
#include "pvlogger.h"
#endif

#ifndef STRING_KEYVALUE_STORE_H_INCLUDED
#include "string_keyvalue_store.h"
#endif

#define HTTP_ENTITY_UNIT_POOLNUM  4
#define DEFAULT_MAX_LINE_BUFFER_SIZE 512
#define DATA_QUEUE_VECTOR_RESERVE_SIZE 4
#define GOOD_HTTP_STATUS_CODE_START_FROM100	100
#define GOOD_HTTP_STATUS_CODE_START_FROM200	200
#define GOOD_HTTP_STATUS_CODE_END_AT299		299
#define HTTP_STATUS_CODE_204_NO_CONTENT		204


enum HTTPContentType
{
    HTTP_CONTENT_NORMAL = 0,					// no chunk header info
    HTTP_CONTENT_NULTIPART,					// for Content-Type : multipart/byteranges
    HTTP_CONTENT_CHUNKED_TRANSFER_ENCODING	// for Transfer-Encoding : chunked
};

#if 1
#define LOGINFO(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG,iLogger,PVLOGMSG_INFO,m);
#else
#define LOGINFO(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m);
#endif



///////////////////////////////////////////////////////////////////////////////////////
// HTTPContentInfoInternal object encapsulates content type/length/range infomation parsing happening
// on header parsing and entity body parsing
struct HTTPContentInfoInternal
{
    uint32 iContentLength;		// for "Content-Length"
    uint32 iContentRangeLeft;	// for "Content-Range"
    uint32 iContentRangeRight;

    // constructor
    HTTPContentInfoInternal() : iBoundaryBuffer(NULL)
    {
        clear();
    }

    // ~destructor
    ~HTTPContentInfoInternal()
    {
        clear();
        if (iBoundaryBuffer) OSCL_ARRAY_DELETE(iBoundaryBuffer);
        iBoundaryBuffer = NULL;
    }

    // clear
    void clear()
    {
        iContentLength     = 0;
        iContentRangeLeft  = 0;
        iContentRangeRight = 0;

        iContentType = HTTP_CONTENT_NORMAL;
        iBoundary.setPtrLen("", 0);
    }

    void get(HTTPContentInfo &aContentInfo)
    {
        aContentInfo.iContentLength = iContentLength;
        aContentInfo.iContentRangeLeft = iContentRangeLeft;
        aContentInfo.iContentRangeRight = iContentRangeRight;
    }

    // operator "="
    HTTPContentInfoInternal &operator=(const HTTPContentInfoInternal& x)
    {
        iContentLength	   = x.iContentLength;
        iContentRangeLeft  = x.iContentRangeLeft;
        iContentRangeRight = x.iContentRangeRight;
        iContentType       = x.iContentType;
        return *this;
    }

    bool parseContentInfo(StringKeyValueStore &aKeyValueStore);
    uint32 getContentType() const
    {
        return (uint32)iContentType;
    }
    // range lengh = range right - range left
    uint32 getContentRangeLength() const
    {
        return (iContentRangeRight == 0 ? 0 : iContentRangeRight - iContentRangeLeft + 1);
    }

    bool parseBoudaryLine(HTTPMemoryFragment &aInputLineData, bool &isFinalBoundary);

private:
    void parseContentRange(const StrPtrLen &aContentRange);
    bool parseContentType(const StrPtrLen &aContentType);
    void verifyTransferEncoding(const StrPtrLen &aTransferEncodingValue);
    bool copyBoundaryString(const char* aBoundaryString, const uint32 aBoundaryStringLength);

private:
    HTTPContentType iContentType;
    char *iBoundaryBuffer;
    StrPtrLen iBoundary;	// for "Content-Type : multipart/byteranges"
};


///////////////////////////////////////////////////////////////////////////////////////
// HTTPParserInput object hides fragment concatenation and grouping for header parsing and output generation
class HTTPParserInput
{

    public:
        // factory method
        static HTTPParserInput *create();

        // destructor
        ~HTTPParserInput();

        // clear
        void clear()
        {
            iDataInQueue.clear();
            iDataOutQueue.clear();
            iHTTPMemFrag.clear();
            iDataInQueueMemFragOffset = 0;
            iLineBufferOccupied = 0;
        }

        void clearOutputQueue()
        {
            iDataOutQueue.clear();
        }

        // add data
        bool push_back(OsclRefCounterMemFrag &aFrag);
        bool getNextCompleteLine(HTTPMemoryFragment &aHttpFrag, bool aHeaderParsed = false);

        // aRequestDataSize==0 means no request size, the function needs to send out whatever amount of data it has,
        // but with one input data fragment each time.
        // return value: actual size, if aRequestDataSize > 0, actual size <= aRequestDataSize
        // actual size = 0, => no data, -1 means error
        int32 getData(HTTPMemoryFragment &aHttpFrag, const uint32 aRequestDataSize = 0);
        bool getOutputMemFrag(OsclRefCounterMemFrag &aMemFrag);

        // This function is for parsing multipart content, specically for the final boundary string like --boundaryString--, which could
        // has no "\r\n", so getNextCompleteLine may not work in this case
        // In general, if iLineBuffer has data, then send out iLineBuffer, then check if input data queue has data, if it has, then send
        // out the first buffer. Return false for no any data (both iLineBuffer and data queue are empty)
        // Note that this function doesn't do "get" (i.e. not changing internal pointers), instead, only does "view"
        bool viewAvailableInputData(HTTPMemoryFragment &aHttpFrag);
        bool empty();

        // pass ending CRLF
        void skipCRLF();

    private:

        // constructor
        HTTPParserInput() : iLineBufferSize(DEFAULT_MAX_LINE_BUFFER_SIZE)
        {
            clear();
        }

        // create iLineBuffer
        bool construct();

        // return value: 0 => not available ; >0 means the offset of the next complete line from the current point
        // -1 error
        int32 isNextLineAvailable(bool aHeaderParsed);
        // called by isNextLineAvailable()
        int32 assemblyLineFragments(HTTPMemoryFragment &aFrag);

        // if aNewMemFragPtr=NULL, no change to memory fragment pointer. isNewFrag=false means update the existing fragment
        // from iDataOutQueue; if isNewFrag=true, get fragment from iDataInQueue
        bool constructOutputFragment(const uint32 aNewMemFragLen, const void *aNewMemFragPtr = NULL, bool isNewFrag = false);
        int32 checkNextLine(HTTPMemoryFragment &aInputDataStream);

    private:
        Oscl_Vector<OsclRefCounterMemFrag, OsclMemAllocator> iDataInQueue;
        Oscl_Vector<RefCounterMemoryFragment, OsclMemAllocator> iDataOutQueue; // RefCounterMemoryFragment defined in http_parcom_internal.h
        uint32 iDataInQueueMemFragOffset;
        HTTPMemoryFragment iHTTPMemFrag; // hold the input data fragment being processed
        char *iLineBuffer;				 // concatenate multiple fragments of each header line
        uint32 iLineBufferSize;
        uint32 iLineBufferOccupied;
};

///////////////////////////////////////////////////////////////////////////////////////
// HTTPParserBaseObject is the base class for header class and entity body class that still needs some kind of
// header parsing inside the entity body

#define LOGGER_TAG "datapath.sourcenode.protocolenginenode" // "protocolenginenode.protocolengine"
//#define LOGGER_TAG "protocolenginenode.protocolengine"


class HTTPParserBaseObject
{
    public:
        int32 parseHeaderFields(HTTPMemoryFragment &aInputLineData, const bool aReplaceOldValue = false);
        bool constructEntityUnit(HTTPParserInput &aParserInput, RefCountHTTPEntityUnit &aEntityUnit);
        void saveEndingCRLF(char *ptr, uint32 len, uint8& aCRLF, bool aNeedReset = true);

        // constructor
        HTTPParserBaseObject(StringKeyValueStore *aKeyValueStore = NULL, PVMFBufferPoolAllocator *aEntityUnitAlloc = NULL) :
                iKeyValueStore(aKeyValueStore), iEntityUnitAlloc(aEntityUnitAlloc), iPrevCRLF(0)
        {
            iLogger = PVLogger::GetLoggerObject(LOGGER_TAG);
        }

    protected:
        // due to the fact that Key-Value store may increase size in the fly, create this method to
        // to wrap up all the details
        // return code comes from HTTPParser return code
        int32 addKeyValuePairToStore(const char *aFieldKey, const uint32 aFieldKeyLength,
                                     const char *aFieldValue, const uint32 aFieldValueLength,
                                     const bool aNeedReplaceOldValue = false);

        int32 addKeyValuePairToStore(const StrCSumPtrLen &aNewKey,
                                     const StrPtrLen &aNewValue,
                                     const bool aNeedReplaceOldValue = false);

    private:
        // return value: 0 normal, 1 end of header
        int32 getNextFieldKeyValuePair(HTTPMemoryFragment &aInputDataStream, char *&aFieldKey, uint32 &aFieldKeyLength,
                                       char *&aFieldValue, uint32 &aFieldValueLength);
        // return value: 0 normal, 1 end of header, 2 ignore
        int32 getLineStartPoint(char *&ptr, int32 &len, const bool isKeyItem);
        // return value: 0 normal, 1 end of header
        int32 parseNextValueItem(HTTPMemoryFragment &aInputDataStream, char *&valueItemPtr, uint32 &valueItemLength, const bool isKeyItem);

        // called by addKeyValuePairToStore, increase the size of the current store
        // due to not enough memory to hold new key-value pair
        bool reallocKeyValueStore(const uint32 aCurrKeyValueSize);

    protected:
        StringKeyValueStore *iKeyValueStore;
        PVMFBufferPoolAllocator *iEntityUnitAlloc;
        uint8 iPrevCRLF; // bit0 -- LF , bit1 -- CR
        PVLogger *iLogger;
};

///////////////////////////////////////////////////////////////////////////////////////
// HTTPParserHeaderObject encapsulates HTTP header parsing, basically parses every field inside the header and save it to
// key-value store, and also triggers content info parsing
class HTTPParserHeaderObject : public HTTPParserBaseObject
{
    public:
        int32 parse(HTTPParserInput &aParserInput, RefCountHTTPEntityUnit &aEntityUnit);
        bool isParsed() const
        {
            return iHeaderParsed;
        }
        // query this case: parsing header completely means parsing the whole response completely
        // in case of no http body with content-length setting to zero
        bool isWholeResponseParsed() const
        {
            return iResponseParsedComplete;
        }
        // check if there are some unsupported headers
        int32 doSanityCheckForResponseHeader();

        // The following "get" functions are for "get" functions of parser
        uint32 getStatusCode() const
        {
            return iStatusCode;
        }
        uint32 getNumFields()
        {
            return (iKeyValueStore == NULL ? 0 : iKeyValueStore->getNumberOfKeyValuePairs());
        }
        uint32 getFieldKeyList(StrPtrLen *&aFieldKeyList)
        {
            return (iKeyValueStore == NULL ? 0 : iKeyValueStore->getCurrentKeyList(aFieldKeyList));
        }
        bool getField(const StrCSumPtrLen &aNewFieldKey, StrPtrLen &aNewFieldValue, const uint32 index = 0)
        {
            return (iKeyValueStore == NULL ? false : iKeyValueStore->getValueByKey(aNewFieldKey, aNewFieldValue, index));
        }
        uint32 getNumberOfFieldsByKey(const StrCSumPtrLen &aNewFieldName)
        {
            return (iKeyValueStore == NULL ? 0 : iKeyValueStore->getNumberOfValuesByKey(aNewFieldName));
        }
        ///////////////////////////////////////////////////////////////////////////

        // get iKeyValueStore and iEntityUnitAlloc, will be used HTTPParserEntityBodyObject
        StringKeyValueStore *getKeyValuesStore() const
        {
            return iKeyValueStore;
        }
        PVMFBufferPoolAllocator *getAllocator() const
        {
            return iEntityUnitAlloc;
        }

        // constructor
        HTTPParserHeaderObject()
        {
            ;
        }

        // destructor
        ~HTTPParserHeaderObject();

        // reset
        void reset()
        {
            iStatusCode				= 0; //200;
            iHttpVersionNum			= 0;
            iHeaderParsed			= false;
            iHeaderFirstLineParsed  = false;
            iResponseParsedComplete = false;
            if (iKeyValueStore) iKeyValueStore->clear();
            iPrevCRLF = 0;
        }

        // factory method, create iKeyValueStore and iEntityUnitAlloc
        static HTTPParserHeaderObject *create(HTTPContentInfoInternal *aContentInfo);

    private:
        // return value: 0 => ok , 1 => data not enough -1 => syntax error
        int32 parseFirstLine(HTTPMemoryFragment &aInputDataStream);
        bool construct(HTTPContentInfoInternal *aContentInfo);
        bool isGoodStatusCode();
        bool checkGood1xxCode();
        bool checkGood2xxCode();
        bool checkHTTPVersion(char* &aPtr);
        bool checkResponseParsedComplete();
        bool checkChunkedTransferEncodingSupported();

    private:
        HTTPContentInfoInternal *iContentInfo;
        uint32 iStatusCode;
        uint32 iHttpVersionNum;
        bool iHeaderParsed;
        bool iHeaderFirstLineParsed;
        bool iResponseParsedComplete;
};

///////////////////////////////////////////////////////////////////////////////////////
// HTTPParserEntityBodyObject encapsulates HTTP entity body parsing. Here we support three types of entity body,
// normal body without any internal headers (usually in HTTP 1.0), multipart/byteranges used in pv fasttrack download
// and chunked transfer encoding, both having internal headers. To handle these three types of content, the following
// classes are designed to remove conditional using polymorphism, or remove type code with class, i.e. derived classes
// implement the interface defined in the base class, parse().
class HTTPParserEntityBodyObject : public HTTPParserBaseObject
{
    public:
        virtual int32 parse(HTTPParserInput &aParserInput, RefCountHTTPEntityUnit &aEntityUnit) = 0;

        // constructor
        HTTPParserEntityBodyObject(StringKeyValueStore *aKeyValueStore,
                                   PVMFBufferPoolAllocator *aEntityUnitAlloc,
                                   HTTPContentInfoInternal *aContentInfo) :
                HTTPParserBaseObject(aKeyValueStore, aEntityUnitAlloc),
                iContentInfo(aContentInfo),
                iCurrentChunkDataLength(0),
                iNumChunks(0),
                iCounter(0)
        {
            ;
        }

        virtual ~HTTPParserEntityBodyObject()
        {
            ;
        }

    protected:
        // used in HTTPParserCTEContentObject and HTTPParserMultipartContentObject
        int32 parseEnityBodyChunkData(HTTPParserInput &aParserInput, RefCountHTTPEntityUnit &aEntityUnit);

    protected:
        HTTPContentInfoInternal *iContentInfo;
        uint32 iCurrentChunkDataLength;
        uint32 iNumChunks;
        uint32 iCounter; // for debugging purpose
};

///////////////////////////////////////////////////////////////////////////////////////
class HTTPParserNormalContentObject : public HTTPParserEntityBodyObject
{
    public:
        int32 parse(HTTPParserInput &aParserInput, RefCountHTTPEntityUnit &aEntityUnit);

        // constructor
        HTTPParserNormalContentObject(StringKeyValueStore *aKeyValueStore,
                                      PVMFBufferPoolAllocator *aEntityUnitAlloc,
                                      HTTPContentInfoInternal *aContentInfo) :
                HTTPParserEntityBodyObject(aKeyValueStore, aEntityUnitAlloc, aContentInfo),
                iCurrTotalLengthObtained(0)
        {
            ;
        }
        virtual ~HTTPParserNormalContentObject()
        {
            ;
        }

    private:
        uint32 iCurrTotalLengthObtained;
};

///////////////////////////////////////////////////////////////////////////////////////
// CTE = Chunked Transfer Encoding
class HTTPParserCTEContentObject : public HTTPParserEntityBodyObject
{
    public:
        int32 parse(HTTPParserInput &aParserInput, RefCountHTTPEntityUnit &aEntityUnit);

        // constructor
        HTTPParserCTEContentObject(StringKeyValueStore *aKeyValueStore,
                                   PVMFBufferPoolAllocator *aEntityUnitAlloc,
                                   HTTPContentInfoInternal *aContentInfo) :
                HTTPParserEntityBodyObject(aKeyValueStore, aEntityUnitAlloc, aContentInfo)
        {
            ;
        }

        virtual ~HTTPParserCTEContentObject()
        {
            ;
        }
    private:
        bool getCTEChunkLength(HTTPMemoryFragment &aInputLineData, int32 &aChunkSize);
        // reset for next chunk parsing
        void reset()
        {
            iCurrentChunkDataLength = 0;
            if (iContentInfo)
            {
                iContentInfo->iContentRangeLeft  = 0;
                iContentInfo->iContentRangeRight = 0;
            }
        }
};

///////////////////////////////////////////////////////////////////////////////////////
class HTTPParserMultipartContentObject : public HTTPParserEntityBodyObject
{
    public:
        int32 parse(HTTPParserInput &aParserInput, RefCountHTTPEntityUnit &aEntityUnit);

        // constructor
        HTTPParserMultipartContentObject(StringKeyValueStore *aKeyValueStore,
                                         PVMFBufferPoolAllocator *aEntityUnitAlloc,
                                         HTTPContentInfoInternal *aContentInfo) :
                HTTPParserEntityBodyObject(aKeyValueStore, aEntityUnitAlloc, aContentInfo)
        {
            reset();
        }

        virtual ~HTTPParserMultipartContentObject()
        {
            ;
        }
    private:
        void reset()
        {
            iBoudaryLineParsed = iHeaderInEntityBodyParsed = false;
            iCurrentChunkDataLength = 0;
            iNumChunks = 0;
        }

        bool needSkipCRLF()
        {
            // iPrevCRLF&0x3!=0x3 means iPrevCRLF hasn't got complete CRLF (i.e.both CR and LF)
            return ((iNumChunks == 0) && ((iPrevCRLF&0x3) != 0x3));
        }

        int32 parseChunkHeader(HTTPParserInput &aParserInput);
        int32 parseChunkBoundaryLine(HTTPParserInput &aParserInput);

    private:
        bool iBoudaryLineParsed;
        bool iHeaderInEntityBodyParsed;

};


#endif // HTTP_PARSER_INTERNAL_H_

