/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */
/* $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;

        };

    }
}
