/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 _DECAF_NET_SOCKET_H_
#define _DECAF_NET_SOCKET_H_

#include <decaf/net/InetAddress.h>
#include <decaf/net/SocketImplFactory.h>
#include <decaf/net/SocketException.h>
#include <decaf/io/InputStream.h>
#include <decaf/io/OutputStream.h>
#include <decaf/io/Closeable.h>
#include <decaf/util/Config.h>

#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/IllegalArgumentException.h>
#include <decaf/net/UnknownHostException.h>
#include <decaf/net/SocketTimeoutException.h>
#include <decaf/io/IOException.h>

namespace decaf{
namespace net{

    class SocketImpl;
    class ServerSocket;

    /**
     *
     * @since 1.0
     */
    class DECAF_API Socket : public decaf::io::Closeable {
    protected:

        // The actual Socket that this Socket represents.
        mutable SocketImpl* impl;

    private:

        // Factory for creating sockets, if not set a Plan TCP Socket is created
        static SocketImplFactory* factory;

        mutable volatile bool created;

        bool connected;
        bool closed;
        bool bound;
        bool inputShutdown;
        bool outputShutdown;

        friend class ServerSocket;

    private:

        Socket( const Socket& );
        Socket& operator= ( const Socket& );

    public:

        /**
         * Creates an unconnected Socket using the set SocketImplFactory or if non is set
         * than the default SockImpl type is created.
         */
        Socket();

        /**
         * Creates a Socket wrapping the provided SocketImpl instance, this Socket is
         * considered unconnected.  The Socket class takes ownership of this SocketImpl
         * pointer and will delete it when the Socket class is destroyed.
         *
         * @param impl
         *      The SocketImpl instance to wrap.
         *
         * @throws NullPointerException if the passed SocketImpl is Null.
         */
        Socket( SocketImpl* impl );

        /**
         * Creates a new Socket instance and connects it to the given address and port.  If
         * there is a SocketImplFactory set then the SokcetImpl is created using the factory
         * otherwise the default Socket implementation is used.
         *
         * If the host parameter is empty then the loop back address is used.
         *
         * @param address
         *      The address to connect to.
         * @param port
         *      The port number to connect to [0...65535]
         *
         * @throws UnknownHostException if the host cannot be resolved.
         * @throws IOException if an I/O error occurs while connecting the Socket.
         * @throws NullPointerException if the InetAddress instance in NULL.
         * @throws IllegalArgumentException if the port if not in range [0...65535]
         */
        Socket( const InetAddress* address, int port );

        /**
         * Creates a new Socket instance and connects it to the given address and port.  If
         * there is a SocketImplFactory set then the SokcetImpl is created using the factory
         * otherwise the default Socket implementation is used.  The Socket will also bind
         * to the local address and port specified.
         *
         * @param address
         *      The address to connect to.
         * @param port
         *      The port number to connect to [0...65535]
         * @param localAddress
         *      The IP address on the local machine to bind to.
         * @param localPort
         *      The port on the local machine to bind to.
         *
         * @throws UnknownHostException if the host cannot be resolved.
         * @throws IOException if an I/O error occurs while connecting the Socket.
         * @throws NullPointerException if the InetAddress instance in NULL.
         * @throws IllegalArgumentException if the port if not in range [0...65535]
         */
        Socket( const InetAddress* address, int port, const InetAddress* localAddress, int localPort );

        /**
         * Creates a new Socket instance and connects it to the given host and port.  If
         * there is a SocketImplFactory set then the SokcetImpl is created using the factory
         * otherwise the default Socket implementation is used.
         *
         * If the host parameter is empty then the loop back address is used.
         *
         * @param host
         *      The host name or IP address to connect to, empty string means loopback.
         * @param port
         *      The port number to connect to [0...65535]
         *
         * @throws UnknownHostException if the host cannot be resolved.
         * @throws IOException if an I/O error occurs while connecting the Socket.
         * @throws IllegalArgumentException if the port if not in range [0...65535]
         */
        Socket( const std::string& host, int port );

        /**
         * Creates a new Socket instance and connects it to the given host and port.  If
         * there is a SocketImplFactory set then the SokcetImpl is created using the factory
         * otherwise the default Socket implementation is used.
         *
         * If the host parameter is empty then the loop back address is used.
         *
         * @param host
         *      The host name or IP address to connect to, empty string means loopback.
         * @param port
         *      The port number to connect to [0...65535]
         * @param localAddress
         *      The IP address on the local machine to bind to.
         * @param localPort
         *      The port on the local machine to bind to.
         *
         * @throws UnknownHostException if the host cannot be resolved.
         * @throws IOException if an I/O error occurs while connecting the Socket.
         * @throws IllegalArgumentException if the port if not in range [0...65535]
         */
        Socket( const std::string& host, int port, const InetAddress* localAddress, int localPort );

        virtual ~Socket();

        /**
         * Binds this Socket to the given local address and port.  If the SocketAddress
         * value is NULL then the Socket will be bound to an available local address and
         * port.
         *
         * @param ipaddress
         *      The local address and port to bind the socket to.
         * @param port
         *      The port on the local machine to bind to.
         *
         * @throws IOException if an error occurs during the bind operation.
         * @throws IllegalArgumentException if the Socket can't process the subclass of SocketAddress
         *         that has been provided.
         */
        virtual void bind( const std::string& ipaddress, int port );

        /**
         * Closes the Socket.  Once closed a Socket cannot be connected or otherwise
         * operated upon, a new Socket instance must be created.
         *
         * @throws IOException if an I/O error occurs while closing the Socket.
         */
        virtual void close();

        /**
         * Connects to the specified destination.
         *
         * @param host
         *      The host name or IP address of the remote host to connect to.
         * @param port
         *      The port on the remote host to connect to.
         *
         * @throws IOException Thrown if a failure occurred in the connect.
         * @throws IllegalArguementException if the timeout value is negative or the endpoint is invalid.
         */
        virtual void connect(const std::string& host, int port);

        /**
         * Connects to the specified destination, with a specified timeout value.  If a connection
         * to the remote host is not established within the specified timeout interval than an
         * SocketTimeoutException is thrown.  A timeout value of zero is treated as an inifinite
         * timeout.
         *
         * @param host
         *      The host name or IP address of the remote host to connect to.
         * @param port
         *      The port on the remote host to connect to.
         * @param timeout
         *      The number of Milliseconds to wait before treating the connection as failed.
         *
         * @throws IOException Thrown if a failure occurred in the connect.
         * @throws SocketTimeoutException if the timeout for connection is exceeded.
         * @throws IllegalArguementException if the timeout value is negative or the endpoint is invalid.
         */
        virtual void connect(const std::string& host, int port, int timeout);

        /**
         * Indicates whether or not this socket is connected to am end point.
         *
         * @return true if connected, false otherwise.
         */
        bool isConnected() const {
            return connected;
        }

        /**
         * @return true if the Socket has been closed.
         */
        bool isClosed() const {
            return closed;
        }

        /**
         * @return true if this Socket has been bound to a Local address.
         */
        bool isBound() const {
            return bound;
        }

        /**
         * @return true if input on this Socket has been shutdown.
         */
        bool isInputShutdown() const {
            return inputShutdown;
        }

        /**
         * @return true if output on this Socket has been shutdown.
         */
        bool isOutputShutdown() const {
            return outputShutdown;
        }

        /**
         * Gets the InputStream for this socket if its connected.  The pointer returned is the
         * property of the associated Socket and should not be deleted by the caller.
         *
         * When the returned InputStream is performing a blocking operation and the underlying
         * connection is closed or otherwise broker the read calls will normally throw an exception
         * to indicate the failure.
         *
         * Closing the InputStream will also close the underlying Socket.
         *
         * @return The InputStream for this socket.
         *
         * @throws IOException if an error occurs during creation of the InputStream, also if the
         *         Socket is not connected or the input has been shutdown previously.
         */
        virtual decaf::io::InputStream* getInputStream();

        /**
         * Gets the OutputStream for this socket if it is connected.  The pointer returned is the
         * property of the Socket instance and should not be deleted by the caller.
         *
         * Closing the returned Socket will also close the underlying Socket.
         *
         * @return the OutputStream for this socket.
         *
         * @throws IOException if an error occurs during the creation of this OutputStream, or
         *         if the Socket is closed or the output has been shutdown previously.
         */
        virtual decaf::io::OutputStream* getOutputStream();

        /**
         * Gets the on the remote host this Socket is connected to.
         *
         * @return the port on the remote host the socket is connected to, or 0 if not connected.
         */
        int getPort() const;

        /**
         * Gets the local port the socket is bound to.
         *
         * @return the local port the socket was bound to, or -1 if the socket is not bound.
         */
        int getLocalPort() const;

        /**
         * Returns the address to which the socket is connected.
         *
         * @return the remote IP address to which this socket is connected, or null if the socket is not connected.
         */
        std::string getInetAddress() const;

        /**
         * Gets the local address to which the socket is bound.
         *
         * @return the local address to which the socket is bound or InetAddress.anyLocalAddress() if the socket is not bound yet.
         */
        std::string getLocalAddress() const;

        /**
         * Shuts down the InputStream for this socket essentially marking it as EOF.  The stream
         * returns EOF for any calls to read after this method has been called.
         *
         * @throws IOException if an I/O error occurs while performing this operation.
         */
        virtual void shutdownInput();

        /**
         * Shuts down the OutputStream for this socket, any data already written to the socket will
         * be sent, any further calls to OuputStream::write will throw an IOException.
         *
         * @throws IOException if an I/O error occurs while performing this operation.
         */
        virtual void shutdownOutput();

        /**
         * Gets the linger time for the socket, SO_LINGER.  A return value of -1 indicates that
         * the option is disabled.
         *
         * @return The linger time in seconds.
         *
         * @throws SocketException if the operation fails.
         */
        virtual int getSoLinger() const;

        /**
         * Sets the linger time (SO_LINGER) using a specified time value, this limits of this
         * value are platform specific.
         *
         * @param state
         *      The state of SO_LINGER, true is on.
         * @param timeout
         *      The linger time in seconds, must be non-negative.
         *
         * @throws SocketException if the operation fails.
         * @throws IllegalArgumentException if state is true and timeout is negative.
         */
        virtual void setSoLinger(bool state, int timeout);

        /**
         * Gets the keep alive flag for this socket, SO_KEEPALIVE.
         *
         * @return true if keep alive is enabled for this socket.
         *
         * @throws SocketException if the operation fails.
         */
        virtual bool getKeepAlive() const;

        /**
         * Enables/disables the keep alive flag for this socket, SO_KEEPALIVE.
         *
         * @param keepAlive
         *      If true, enables the flag.
         *
         * @throws SocketException if the operation fails.
         */
        virtual void setKeepAlive(bool keepAlive);

        /**
         * Gets the receive buffer size for this socket, SO_RCVBUF.  This is the buffer used
         * by the underlying platform socket to buffer received data.
         *
         * @return the receive buffer size in bytes.
         *
         * @throws SocketException if the operation fails.
         */
        virtual int getReceiveBufferSize() const;

        /**
         * Sets the receive buffer size for this socket, SO_RCVBUF.
         *
         * @param size
         *      Number of bytes to set the receive buffer to.
         *
         * @throws SocketException if the operation fails.
         * @throws IllegalArgumentException if the value is zero or negative.
         */
        virtual void setReceiveBufferSize(int size);

        /**
         * Gets the reuse address flag, SO_REUSEADDR.
         *
         * @return True if the address can be reused.
         *
         * @throws SocketException if the operation fails.
         */
        virtual bool getReuseAddress() const;

        /**
         * Sets the reuse address flag, SO_REUSEADDR.
         *
         * @param reuse
         *      If true, sets the flag.
         *
         * @throws SocketException if the operation fails.
         */
        virtual void setReuseAddress(bool reuse);

        /**
         * Gets the send buffer size for this socket, SO_SNDBUF, this value is used by the platform
         * socket to buffer data written to the socket.
         *
         * @return the size in bytes of the send buffer.
         *
         * @throws SocketException if the operation fails.
         */
        virtual int getSendBufferSize() const;

        /**
         * Gets the send buffer size for this socket, SO_SNDBUF, this value is used by the platform
         * socket to buffer data written to the socket.
         *
         * @param size
         *      The number of bytes to set the send buffer to, must be larger than zero.
         *
         * @throws SocketException if the operation fails.
         * @throws IllegalArgumentException if the value is zero or negative.
         */
        virtual void setSendBufferSize(int size);

        /**
         * Gets the timeout for socket operations, SO_TIMEOUT.
         *
         * @return The timeout in milliseconds for socket operations.
         *
         * @throws SocketException Thrown if unable to retrieve the information.
         */
        virtual int getSoTimeout() const;

        /**
         * Sets the timeout for socket operations, SO_TIMEOUT.  A value of zero indicates that timeout
         * is infinite for operations on this socket.
         *
         * @param timeout
         *      The timeout in milliseconds for socket operations.
         *
         * @throws SocketException Thrown if unable to set the information.
         * @throws IllegalArgumentException if the timeout value is negative.
         */
        virtual void setSoTimeout(int timeout);

        /**
         * Gets the Status of the TCP_NODELAY setting for this socket.
         *
         * @return true if TCP_NODELAY is enabled for the socket.
         *
         * @throws SocketException Thrown if unable to set the information.
         */
        virtual bool getTcpNoDelay() const;

        /**
         * Sets the Status of the TCP_NODELAY param for this socket., this setting is used
         * to disable or enable Nagle's algorithm on the Socket.
         *
         * @param value
         *      The setting for the socket's TCP_NODELAY option, true to enable.
         *
         * @throws SocketException Thrown if unable to set the information.
         */
        virtual void setTcpNoDelay(bool value);

        /**
         * Gets the Traffic Class setting for this Socket, sometimes referred to as Type of
         * Service setting.  This setting is dependent on the underlying network implementation
         * for the platform this Socket runs on and is not guaranteed to have any effect.
         *
         * Refer to your platforms network documentation regarding support for this setting.
         *
         * @return the bitset result of querying the traffic class setting.
         *
         * @throws SocketException if an error is encountered while performing this operation.
         */
        virtual int getTrafficClass() const;

        /**
         * Gets the Traffic Class setting for this Socket, sometimes referred to as Type of
         * Service setting.  This setting is dependent on the underlying network implementation
         * for the platform this Socket runs on and is not guaranteed to have any effect.
         *
         * Refer to your platforms network documentation regarding support for this setting.
         *
         * @param value
         *      The integer value representing the traffic class setting bitset.
         *
         * @throws SocketException if an error is encountered while performing this operation.
         * @throws IllegalArgumentException if the value is not in the range [0..255].
         */
        virtual void setTrafficClass(int value);

        /**
         * Gets the value of the OOBINLINE for this socket.
         *
         * @return true if OOBINLINE is enabled, false otherwise.
         *
         * @throws SocketException if an error is encountered while performing this operation.
         */
        virtual bool getOOBInline() const;

        /**
         * Sets the value of the OOBINLINE for this socket, by default this option is disabled.  If
         * enabled the urgent data is read inline on the Socket's InputStream, no notification is give.
         *
         * @return true if OOBINLINE is enabled, false otherwise.
         *
         * @throws SocketException if an error is encountered while performing this operation.
         */
        virtual void setOOBInline(bool value);

        /**
         * Sends on byte of urgent data to the Socket.
         *
         * @param data
         *      The value to write as urgent data, only the lower eight bits are sent.
         *
         * @throws IOException if an I/O error occurs while performing this operation.
         */
        virtual void sendUrgentData(int data);

        /**
         * @return a string representing this Socket.
         */
        virtual std::string toString() const;

    public:

        /**
         * Sets the instance of a SocketImplFactory that the Socket class should use when new
         * instances of this class are created.  This method is only allowed to be used once
         * during the lifetime of the application.
         *
         * @param factory
         *      The instance of a SocketImplFactory to use when new Socket objects are created.
         *
         * @throws IOException if an I/O error occurs while performing this operation.
         * @throws SocketException if this method has already been called with a valid factory.
         */
        static void setSocketImplFactory( SocketImplFactory* factory );

    protected:

        // Flags the Socket instance as created, bound and connected when its connected
        // via a ServerSocket accept call.
        void accepted();

        // Sets up a connected socket for the constructors that take connection arguments.
        void initSocketImpl( const std::string& address, int port, const InetAddress* localAddress, int localPort );

        // Check for already closed and throw an error if so.
        void checkClosed() const;

        // Create but don't connect the underlying OS Socket instance, if not already created.
        void ensureCreated() const;

    };

}}

#endif /*_DECAF_NET_SOCKET_H_*/
