/*
 * 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.
 */
#include <activemq/util/Config.h>

#if defined(HAVE_WINSOCK2_H)
    #include <Winsock2.h>
    #include <Ws2tcpip.h>
    #include <sys/stat.h>
    #define stat _stat
#else
    #include <unistd.h>
    #include <netdb.h>
    #include <fcntl.h>
    #include <sys/file.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <netinet/tcp.h>
#endif

#ifndef SHUT_RDWR
    #define SHUT_RDWR 2 // Winsock2 doesn't seem to define this
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <sys/types.h>

#include "TcpSocket.h"
#include "SocketInputStream.h"
#include "SocketOutputStream.h"
#include "SocketError.h"

using namespace activemq::network;
using namespace activemq::io;

#if defined(HAVE_WINSOCK2_H)

    // Static socket initializer needed for winsock

    TcpSocket::StaticSocketInitializer::StaticSocketInitializer() {
        socketInitError = NULL;
        const WORD version_needed = MAKEWORD(2,2); // lo-order byte: major version
        WSAData temp;
        if( WSAStartup( version_needed, &temp ) ){
           clear();
           socketInitError = new SocketException ( __FILE__, __LINE__,
               "winsock.dll was not found");
        }
    }
    TcpSocket::StaticSocketInitializer::~StaticSocketInitializer() {
        clear();
        WSACleanup();
    }

    // Create static instance of the socket initializer.
    TcpSocket::StaticSocketInitializer TcpSocket::staticSocketInitializer;

#endif

////////////////////////////////////////////////////////////////////////////////
TcpSocket::TcpSocket() throw (SocketException)
:
    socketHandle( INVALID_SOCKET_HANDLE ),
    inputStream( NULL ),
    outputStream( NULL )
{

    try {

#if defined(HAVE_WINSOCK2_H)
        if( staticSocketInitializer.getSocketInitError() != NULL ) {
            throw *staticSocketInitializer.getSocketInitError();
        }
#endif
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
TcpSocket::TcpSocket( SocketHandle socketHandle )
:
    socketHandle( INVALID_SOCKET_HANDLE ),
    inputStream( NULL ),
    outputStream( NULL )
{
    try {

#if defined(HAVE_WINSOCK2_H)
        if( staticSocketInitializer.getSocketInitError() != NULL ) {
            throw *staticSocketInitializer.getSocketInitError();
        }
#endif

        this->socketHandle = socketHandle;
        this->inputStream = new SocketInputStream( socketHandle );
        this->outputStream = new SocketOutputStream( socketHandle );
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
TcpSocket::~TcpSocket()
{
    // No shutdown, just close - dont want blocking destructor.
    close();

    // Destroy the input stream.
    if( inputStream != NULL ){
        delete inputStream;
        inputStream = NULL;
    }

    // Destroy the output stream.
    if( outputStream != NULL ){
        delete outputStream;
        outputStream = NULL;
    }
}

////////////////////////////////////////////////////////////////////////////////
InputStream* TcpSocket::getInputStream(){
    return inputStream;
}

////////////////////////////////////////////////////////////////////////////////
OutputStream* TcpSocket::getOutputStream(){
    return outputStream;
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::connect(const char* host, int port) throw ( SocketException )
{
    try{

        if( isConnected() ) {
            throw SocketException( __FILE__, __LINE__,
                "Socket::connect - Socket already connected.  host: %s, port: %d", host, port );
        }

        // Create the socket.
        checkResult( (int)(socketHandle = ::socket(AF_INET, SOCK_STREAM, 0)) );

        // Check port value.
        if( port <= 0 || port > 65535 ) {
            close();
            throw SocketException ( __FILE__, __LINE__,
                "Socket::connect- Port out of range: %d", port );
        }

#ifdef SO_NOSIGPIPE // Don't want to get a SIGPIPE on FreeBSD and Mac OS X

        int optval = 1;
        checkResult( ::setsockopt( socketHandle, SOL_SOCKET, SO_NOSIGPIPE, (char*)&optval, sizeof(optval)) );

#endif

        sockaddr_in target_addr;
        target_addr.sin_family = AF_INET;
        target_addr.sin_port = htons( ( short ) port );
        target_addr.sin_addr.s_addr = 0; // To be set later down...
        memset( &target_addr.sin_zero, 0, sizeof( target_addr.sin_zero ) );

        // Resolve name
#if defined(HAVE_STRUCT_ADDRINFO)
        addrinfo hints;
        memset( &hints, 0, sizeof(addrinfo) );
        hints.ai_family = PF_INET;
        struct addrinfo *res_ptr = NULL;

        checkResult( ::getaddrinfo( host, NULL, &hints, &res_ptr ) );

        assert(res_ptr->ai_addr->sa_family == AF_INET);
        // Porting: On both 32bit and 64 bit systems that we compile to soo far, sin_addr
        // is a 32 bit value, not an unsigned long.
        assert( sizeof( ( ( sockaddr_in* )res_ptr->ai_addr )->sin_addr.s_addr ) == 4 );
        target_addr.sin_addr.s_addr = ( ( sockaddr_in* )res_ptr->ai_addr )->sin_addr.s_addr;
        freeaddrinfo( res_ptr );
#else
        struct ::hostent *he = ::gethostbyname(host);
        if( he == NULL ) {
            throw SocketException( __FILE__, __LINE__, "Failed to resolve hostname" );
        }
        target_addr.sin_addr.s_addr = *((in_addr_t *)he->h_addr);
#endif

        // Attempt the connection to the server.
        checkResult( ::connect( socketHandle,
                            ( const sockaddr * )&target_addr,
                            sizeof( target_addr ) ) );

        // Destroy the input stream.
        if( inputStream != NULL ){
            delete inputStream;
            inputStream = NULL;
        }

        // Destroy the output stream.
        if( outputStream != NULL ){
            delete outputStream;
            outputStream = NULL;
        }

        // Create an input/output stream for this socket.
        inputStream = new SocketInputStream( socketHandle );
        outputStream = new SocketOutputStream( socketHandle );
    }
    catch( SocketException& ex ) {
        ex.setMark( __FILE__, __LINE__);
        try{ close(); } catch( cms::CMSException& cx){ /* Absorb */ }
        throw ex;
    }
    catch( ... ){
        try{ close(); } catch( cms::CMSException& cx){ /* Absorb */ }
        throw SocketException( __FILE__, __LINE__, "connect() caught unknown exception");
    }
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::close() throw( cms::CMSException )
{
    // Close the input stream.
    if( inputStream != NULL ){
        inputStream->close();
    }

    // Close the output stream.
    if( outputStream != NULL ){
        outputStream->close();
    }

    if( isConnected() )
    {
        ::shutdown( socketHandle, SHUT_RDWR );

        #if !defined(HAVE_WINSOCK2_H)
            ::close( socketHandle );
        #else
           ::closesocket( socketHandle );
        #endif

       socketHandle = INVALID_SOCKET_HANDLE;
    }
}

////////////////////////////////////////////////////////////////////////////////
int TcpSocket::getSoLinger() const throw( SocketException ){

   try{
        linger value;
        socklen_t length = sizeof( value );
        checkResult(::getsockopt( socketHandle, SOL_SOCKET, SO_LINGER, (char*)&value, &length ));

        return value.l_onoff? value.l_linger : 0;
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::setSoLinger( int dolinger ) throw( SocketException ){

    try{
        linger value;
        value.l_onoff = dolinger != 0;
        value.l_linger = dolinger;
        checkResult(::setsockopt( socketHandle, SOL_SOCKET, SO_LINGER, (char*)&value, sizeof(value) ));
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
bool TcpSocket::getKeepAlive() const throw( SocketException ){

    try{
        int value;
        socklen_t length = sizeof( int );
        checkResult(::getsockopt( socketHandle, SOL_SOCKET, SO_KEEPALIVE, (char*)&value, &length ));
        return value != 0;
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::setKeepAlive( const bool keepAlive ) throw( SocketException ){

    try{
        int value = keepAlive? 1 : 0;
        checkResult(::setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE, (char*)&value, sizeof(int)) );
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
int TcpSocket::getReceiveBufferSize() const throw( SocketException ){

    try{
        int value;
        socklen_t length = sizeof( value );
        checkResult(::getsockopt( socketHandle, SOL_SOCKET, SO_RCVBUF, (char*)&value, &length ));
        return value;
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::setReceiveBufferSize( int size ) throw( SocketException ){

    try{
        checkResult(::setsockopt( socketHandle, SOL_SOCKET, SO_RCVBUF, (char*)&size, sizeof(size) ));
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
bool TcpSocket::getReuseAddress() const throw( SocketException ){

    try{
        int value;
        socklen_t length = sizeof( int );
        checkResult(::getsockopt( socketHandle, SOL_SOCKET, SO_REUSEADDR, (char*)&value, &length ));
        return value != 0;
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::setReuseAddress( bool reuse ) throw( SocketException ){

    try{
        int value = reuse? 1 : 0;
        checkResult(::setsockopt( socketHandle, SOL_SOCKET, SO_REUSEADDR, (char*)&value, sizeof(int) ));
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
int TcpSocket::getSendBufferSize() const throw( SocketException ){

    try{
        int value;
        socklen_t length = sizeof( value );
        checkResult(::getsockopt( socketHandle, SOL_SOCKET, SO_SNDBUF, (char*)&value, &length ));
        return value;
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::setSendBufferSize( int size ) throw( SocketException ){

    try{
        checkResult(::setsockopt( socketHandle, SOL_SOCKET, SO_SNDBUF, (char*)&size, sizeof(size) ));
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::setSoTimeout ( const int millisecs ) throw ( SocketException )
{
    try{

#if !defined(HAVE_WINSOCK2_H)
        timeval timot;
        timot.tv_sec = millisecs / 1000;
        timot.tv_usec = (millisecs % 1000) * 1000;
#else
        int timot = millisecs;
#endif

        checkResult(::setsockopt( socketHandle, SOL_SOCKET, SO_RCVTIMEO, (const char*) &timot, sizeof (timot) ));
        checkResult(::setsockopt( socketHandle, SOL_SOCKET, SO_SNDTIMEO, (const char*) &timot, sizeof (timot) ));
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
int TcpSocket::getSoTimeout() const throw( SocketException )
{
    try{

#if !defined(HAVE_WINSOCK2_H)
        timeval timot;
        timot.tv_sec = 0;
        timot.tv_usec = 0;
        socklen_t size = sizeof(timot);
#else
        int timot = 0;
        int size = sizeof(timot);
#endif

        checkResult(::getsockopt(socketHandle, SOL_SOCKET, SO_RCVTIMEO, (char*) &timot, &size));

#if !defined(HAVE_WINSOCK2_H)
        return (timot.tv_sec * 1000) + (timot.tv_usec / 1000);
#else
        return timot;
#endif

    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )

}

////////////////////////////////////////////////////////////////////////////////
bool TcpSocket::getTcpNoDelay() const throw ( cms::CMSException ) {

    try{
        int value;
        socklen_t length = sizeof( int );
        checkResult(::getsockopt( socketHandle, IPPROTO_TCP, TCP_NODELAY, (char*)&value, &length ));
        return value != 0;
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::setTcpNoDelay( bool value ) throw ( cms::CMSException ) {

    try{
        int ivalue = value ? 1 : 0;
        checkResult(::setsockopt( socketHandle, IPPROTO_TCP, TCP_NODELAY, (char*)&ivalue, sizeof(int) ));
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

////////////////////////////////////////////////////////////////////////////////
void TcpSocket::checkResult( int value ) const throw (SocketException) {

    if( value < 0 ){
        throw SocketException( __FILE__, __LINE__,
            SocketError::getErrorString().c_str() );
    }
}


