/*
 * 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 <sys/select.h>
    #include <sys/socket.h>
#else
    #include <Winsock2.h>
#endif

#ifdef HAVE_SYS_IOCTL_H
#define BSD_COMP /* Get FIONREAD on Solaris2. */
#include <sys/ioctl.h>
#endif

// Pick up FIONREAD on Solaris 2.5.
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif

#include <activemq/network/SocketInputStream.h>
#include <activemq/network/SocketError.h>
#include <activemq/io/IOException.h>
#include <activemq/util/Character.h>
#include <activemq/exceptions/UnsupportedOperationException.h>
#include <stdlib.h>
#include <string>
#include <stdio.h>
#include <iostream>

using namespace activemq;
using namespace activemq::network;
using namespace activemq::io;
using namespace activemq::util;
using namespace activemq::exceptions;
using namespace std;

////////////////////////////////////////////////////////////////////////////////
SocketInputStream::SocketInputStream( network::Socket::SocketHandle socket ) {

    this->socket = socket;
    this->closed = false;
}

////////////////////////////////////////////////////////////////////////////////
SocketInputStream::~SocketInputStream() {}

////////////////////////////////////////////////////////////////////////////////
void SocketInputStream::close() throw( cms::CMSException ){
    this->closed = true;
}

////////////////////////////////////////////////////////////////////////////////
std::size_t SocketInputStream::available() const throw (activemq::io::IOException){

// The windows version
#if defined(HAVE_WINSOCK2_H)

    unsigned long numBytes = 0;

    if( ::ioctlsocket(socket, FIONREAD, &numBytes ) == SOCKET_ERROR ){
        throw SocketException(
            __FILE__, __LINE__,
            "SocketInputStream::available - ioctlsocket failed" );
    }

    return (std::size_t)numBytes;

#else // !defined(HAVE_WINSOCK2_H)

    // If FIONREAD is defined - use ioctl to find out how many bytes
    // are available.
    #if defined(FIONREAD)

        std::size_t numBytes = 0;
        if( ::ioctl (socket, FIONREAD, &numBytes) != -1 ){
            return numBytes;
        }

    #endif

    // If we didn't get anything we can use select.  This is a little
    // less functional.  We will poll on the socket - if there is data
    // available, we'll return 1, otherwise we'll return zero.
    #if defined(HAVE_SELECT)

        fd_set rd;
        FD_ZERO(&rd);
        FD_SET( socket, &rd );
        struct timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        int returnCode = ::select(socket+1, &rd, NULL, NULL, &tv);
        if(returnCode == -1){
            throw IOException(__FILE__, __LINE__, SocketError::getErrorString().c_str() );
        }
        return (returnCode == 0)? 0 : 1;

    #else

        return 0;

    #endif /* HAVE_SELECT */


#endif // !defined(HAVE_WINSOCK2_H)
}

////////////////////////////////////////////////////////////////////////////////
unsigned char SocketInputStream::read() throw (IOException){

    unsigned char c;
    std::size_t len = read( &c, 1 );
    if( len != sizeof(c) && !closed ){
        throw IOException( __FILE__, __LINE__,
            "activemq::io::SocketInputStream::read - failed reading a byte");
    }

    return c;
}

////////////////////////////////////////////////////////////////////////////////
std::size_t SocketInputStream::read( unsigned char* buffer,
                                     std::size_t bufferSize ) throw (IOException)
{
    int len = 0;

    // Loop to ignore any signal interruptions that occur during the read.
    do {

        // Read data from the socket.
        len = ::recv(socket, (char*)buffer, (int)bufferSize, 0);

        // Check for a closed socket.
        if( len == 0 || closed ){
            throw IOException( __FILE__, __LINE__,
                "activemq::io::SocketInputStream::read - The connection is broken" );
        }

    } while( !closed && len == -1 &&
             SocketError::getErrorCode() == SocketError::INTERRUPTED );

    // Check for error.
    if( len == -1 ){

        // Otherwise, this was a bad error - throw an exception.
        throw IOException( __FILE__, __LINE__,
                "activemq::io::SocketInputStream::read - %s", SocketError::getErrorString().c_str() );
    }

    return len;
}

////////////////////////////////////////////////////////////////////////////////
std::size_t SocketInputStream::skip( std::size_t num AMQCPP_UNUSED )
    throw ( io::IOException, exceptions::UnsupportedOperationException ) {

    throw exceptions::UnsupportedOperationException(
        __FILE__, __LINE__,
        "SocketInputStream::skip - skip() method is not supported");
}

