/*
 * Copyright (C) 2007-2023 Xagasoft, All rights reserved.
 *
 * This file is part of the libbu++ library and is released under the
 * terms of the license contained in the file LICENSE.
 */

#ifndef BU_PROTOCOL_WEB_SOCKET_H
#define BU_PROTOCOL_WEB_SOCKET_H

#include "bu/protocol.h"
#include "bu/hash.h"

#include "bu/mutex.h"

namespace Bu
{
    class ProtocolWebSocket : public Bu::Protocol
    {
    public:
        enum Operation
        {
            Continuation = 0,
            Text         = 1,
            Binary       = 2,
            ConClose     = 8,
            Ping         = 9,
            Pong         = 10
        };

    public:
        ProtocolWebSocket();
        virtual ~ProtocolWebSocket();

        virtual void onNewConnection( Bu::Client *pClient );
        virtual void onNewData( Bu::Client *pClient );

        /**
         * Return true to continue the connection, return false to disconnect.
         * Feel free to modify the headers out list to add or remove http
         * headers to go to the client.
         */
        virtual bool onProcessHeaders( Bu::StringList &lHeadersOut );
        virtual void onHandshakeComplete()=0;
        virtual void onNewMessage( const Bu::String &sData, Operation eOp )=0;
        void writeMessage( const Bu::String &sData, Operation eOp=Text );

    private:
        bool stateProtoId();
        bool stateHandshake();
        bool processHeaders();
        bool headerMatch( const Bu::String &sKey, const Bu::String &sValue );
        bool readHttpHdrLine( Bu::String &sLine );
        bool parseMessage();

    private:
        enum Status
        {
            stProtoId       = 0,
            stHandshake     = 1,
            stReady         = 10
        };

    protected:
        Bu::Client *pClient;
        Status eStatus;
        Bu::String sPath;
        Bu::Hash<Bu::String, Bu::StringList> hHeader;
        Bu::Mutex mClient;
    };
}

#endif
