/*
 * Copyright 2009 Funambol, Inc.
 *
 * 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.
 */

/* $Id$ */

#pragma once

#include <platform.h>

#if defined(PLATFORM_WINDOWS)
#undef _WINSOCKAPI_
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#else
#include <sys/socket.h>
#endif

#include <string>
#include <vector>

#include <commontypes.h>

#include <Logger/Logger.h>

namespace NS_DM_Client
{

    namespace NS_NotificationListener
    {

        class IDataSink;

        class UDPListener
        {
        public:
            typedef unsigned short  port_t;
#if defined(PLATFORM_WINDOWS)
            typedef SOCKET socket_t;
#else
            typedef int socket_t;
#endif

            enum
            {
                INVALID_PORT    = 0
            };

            enum
            {
                DEFAULT_READ_BUFFER_SIZE = 4*1024
            };

            static const char ANY_ADDR[];

            UDPListener(NS_Logging::Logger& logger);
            virtual ~UDPListener();

            /// Initialize with IP address, port and optional read buffer size
            bool    Init(const in_addr& ipAddr, port_t port, size_t readBufferSize = DEFAULT_READ_BUFFER_SIZE);
            /// Initialize with IP address, port and optional read buffer size
            bool    Init(const char* ipAddr, port_t port, size_t readBufferSize = DEFAULT_READ_BUFFER_SIZE);

            /// Starts socket listening
            bool    Listen(IDataSink* dataSink);

            /// Stops socket listening for incoming data
            bool    Stop();

            void    SetSettings(bool dumpMessage, const char* dumpPath = NULL);

        protected:
            virtual bool    libInit();

            static void S_generateStopMessage(std::string& msg);

            void dump(const char* data, size_t size);

            bool	closeSocket();

        private:
            bool        m_libInitialized;
            socket_t    m_sock;
            volatile bool  m_stop;

            buffer_t    m_buf;

            std::string    STOP_MESSAGE;

            in_addr     m_addr;
            port_t      m_port;

            NS_Logging::Logger&     m_logger;

            bool m_dumpMessage;
            String	m_dumpPath;

        };

    }
}
