/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#include <config.h>
#include <platform.h>

#undef STRICT
#undef MAX_PRIORITY
#undef MIN_PRIORITY

#include <gnu/java/net/PlainSocketImpl.h>
#include <gnu/java/net/PlainSocketImpl$SocketInputStream.h>
#include <gnu/java/net/PlainSocketImpl$SocketOutputStream.h>
#include <java/io/IOException.h>
#include <java/net/BindException.h>
#include <java/net/ConnectException.h>
#include <java/net/InetAddress.h>
#include <java/net/InetSocketAddress.h>
#include <java/net/SocketException.h>
#include <java/net/SocketTimeoutException.h>
#include <java/lang/InternalError.h>
#include <java/lang/Object.h>
#include <java/lang/Boolean.h>
#include <java/lang/Class.h>
#include <java/lang/Integer.h>
#include <java/lang/Thread.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/IllegalArgumentException.h>

union SockAddr
{
  struct sockaddr_in address;
#ifdef HAVE_INET6
  struct sockaddr_in6 address6;
#endif
};

void
gnu::java::net::PlainSocketImpl::create (jboolean stream)
{
  SOCKET sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);

  if (sock == INVALID_SOCKET)
    {
      _Jv_ThrowIOException ();
    }

  // Cast this to a HANDLE so we can make
  // it non-inheritable via _Jv_platform_close_on_exec.
  HANDLE hSocket = (HANDLE) sock;
  _Jv_platform_close_on_exec (hSocket);

  // We use native_fd in place of fd here.  From leaving fd null we avoid
  // the double close problem in FileDescriptor.finalize.
  native_fd = (jint) hSocket;
}

void
gnu::java::net::PlainSocketImpl::bind (::java::net::InetAddress *host, jint lport)
{
  union SockAddr u;
  struct sockaddr *ptr = (struct sockaddr *) &u.address;
  jbyteArray haddress = host->addr;
  jbyte *bytes = elements (haddress);
  int len = haddress->length;

  if (len == 4)
    {
      u.address.sin_family = AF_INET;

      if (host != NULL)
        memcpy (&u.address.sin_addr, bytes, len);
      else
        u.address.sin_addr.s_addr = htonl (INADDR_ANY);

      len = sizeof (struct sockaddr_in);
      u.address.sin_port = htons (lport);
    }
#ifdef HAVE_INET6
  else if (len == 16)
    {
      u.address6.sin6_family = AF_INET6;
      memcpy (&u.address6.sin6_addr, bytes, len);
      len = sizeof (struct sockaddr_in6);
      u.address6.sin6_port = htons (lport);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));

  if (::bind (native_fd, ptr, len) != SOCKET_ERROR)
    {
      socklen_t addrlen = sizeof(u);

      if (lport != 0)
        localport = lport;
      else if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)
        localport = ntohs (u.address.sin_port);
      else
        goto error;

      return;
    }

error:
  DWORD dwErrorCode = WSAGetLastError ();
  throw new ::java::net::BindException (_Jv_WinStrError (dwErrorCode));
}

static void
throwConnectException (DWORD dwErrorCode)
{
  throw new ::java::net::ConnectException (_Jv_WinStrError (dwErrorCode));
}

static void
throwConnectException ()
{
  throwConnectException (WSAGetLastError ());
}

void
gnu::java::net::PlainSocketImpl::connect (::java::net::SocketAddress *addr,
                                     jint timeout)
{
  ::java::net::InetSocketAddress *tmp = (::java::net::InetSocketAddress*) addr;
  ::java::net::InetAddress *host = tmp->getAddress();
  jint rport = tmp->getPort();

  // Set the SocketImpl's address and port fields before we try to
  // connect.  Note that the fact that these are set doesn't imply
  // that we're actually connected to anything.  We need to record
  // this data before we attempt the connect, since non-blocking
  // SocketChannels will use this and almost certainly throw timeout
  // exceptions.
  address = host;
  port = rport;

  union SockAddr u;
  socklen_t addrlen = sizeof(u);
  jbyteArray haddress = host->addr;
  jbyte *bytes = elements (haddress);
  int len = haddress->length;
  struct sockaddr *ptr = (struct sockaddr *) &u.address;
  
  if (len == 4)
    {
      u.address.sin_family = AF_INET;
      memcpy (&u.address.sin_addr, bytes, len);
      len = sizeof (struct sockaddr_in);
      u.address.sin_port = htons (rport);
    }
#ifdef HAVE_INET6
  else if (len == 16)
    {
      u.address6.sin6_family = AF_INET6;
      memcpy (&u.address6.sin6_addr, bytes, len);
      len = sizeof (struct sockaddr_in6);
      u.address6.sin6_port = htons (rport);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));

  if (timeout > 0)
    {
      // FIXME: we're creating a fresh WSAEVENT for each connect().
      WSAEventWrapper aWSAEventWrapper(native_fd, FD_CONNECT);
      WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();

      if (::connect (native_fd, ptr, len) == SOCKET_ERROR)
      {
        if (WSAGetLastError () != WSAEWOULDBLOCK)
          throwConnectException ();

        DWORD dwRet =
          WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);
            // use true, false instead of TRUE, FALSE because the
            // MS constants got undefined

        // Reset and ignore our thread's interrupted flag.
        // It's not possible to interrupt these sort of
        // operations on Win32 anyway.
        ::java::lang::Thread::interrupted();

        if (dwRet == WSA_WAIT_FAILED)
          throwConnectException ();
        else if (dwRet == WSA_WAIT_TIMEOUT)
          throw new ::java::net::SocketTimeoutException
            (JvNewStringUTF ("connect timed out"));
            
        // If we get here, we still need to check whether the actual
        // connect() succeeded. Use any socket-specific error code
        // instead of the thread-based one.
        int nErrCode; int nErrLen=sizeof(nErrCode);
        if (::getsockopt(native_fd, SOL_SOCKET, SO_ERROR, (char*) &nErrCode,
          &nErrLen) == SOCKET_ERROR)
          {
            throwConnectException ();
          }
        
        if (nErrCode != NO_ERROR)
          {
            throwConnectException (nErrCode);
          }
      }
    }
  else
    {
      if (::connect (native_fd, ptr, len) == SOCKET_ERROR)
        throwConnectException();
    }

  // A bind may not have been done on this socket; if so, set localport now.
  if (localport == 0)
    {
      if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)
        localport = ntohs (u.address.sin_port);
      else
        throwConnectException();
    }
}

void
gnu::java::net::PlainSocketImpl::listen (jint backlog)
{
  if (::listen (native_fd, backlog) == SOCKET_ERROR)
    {
      _Jv_ThrowIOException ();
    }
}

void
gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s)
{
  union SockAddr u;
  socklen_t addrlen = sizeof(u);
  HANDLE hSocket = 0;
  SOCKET new_socket = 0;

  if (timeout > 0)
    {
      // FIXME: we're creating a fresh WSAEVENT for each accept().
      // One possible alternative would be that native_fd really points
      // to an extended structure consisting of the SOCKET, its
      // associated WSAEVENT, etc.
      WSAEventWrapper aWSAEventWrapper(native_fd, FD_ACCEPT);
      WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();

      for (;;)
      {
        new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);

        if (new_socket != INVALID_SOCKET)
        {
          // This new child socket is nonblocking because the parent
          // socket became nonblocking via the WSAEventSelect() call,
          // so we set its mode back to blocking.
          WSAEventSelect (new_socket, hEvent, 0);
            // undo the hEvent <-> FD_ACCEPT association inherited
            // inherited from our parent socket

          unsigned long lSockOpt = 0L;
            // blocking mode
          if (ioctlsocket(new_socket, FIONBIO, &lSockOpt) == SOCKET_ERROR)
          {
            goto error;
          }
          break;
        }
        else if (WSAGetLastError () != WSAEWOULDBLOCK)
          {
            goto error;
          }

        DWORD dwRet =
          WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);
            // use true, false instead of TRUE, FALSE because the
            // MS constants got undefined

        // Reset and ignore our thread's interrupted flag.
        ::java::lang::Thread::interrupted();

        if (dwRet == WSA_WAIT_FAILED)
          goto error;
        else if (dwRet == WSA_WAIT_TIMEOUT)
          throw new ::java::net::SocketTimeoutException
            (JvNewStringUTF ("Accept timed out"));
      }
    }
  else
    {
      new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);
    }

  if (new_socket == INVALID_SOCKET)
    goto error;

  // Cast this to a HANDLE so we can make
  // it non-inheritable via _Jv_platform_close_on_exec.
  hSocket = (HANDLE) new_socket;
  _Jv_platform_close_on_exec (hSocket);

  jbyteArray raddr;
  jint rport;
  if (u.address.sin_family == AF_INET)
    {
      raddr = JvNewByteArray (4);
      memcpy (elements (raddr), &u.address.sin_addr, 4);
      rport = ntohs (u.address.sin_port);
    }
#ifdef HAVE_INET6
  else if (u.address.sin_family == AF_INET6)
    {
      raddr = JvNewByteArray (16);
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
      rport = ntohs (u.address6.sin6_port);
    }
#endif
  else
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));

  s->native_fd = (jint) hSocket;
  s->localport = localport;
  s->address = ::java::net::InetAddress::getByAddress (raddr);
  s->port = rport;
  return;

 error:
  _Jv_ThrowIOException ();
}

// Close(shutdown) the socket.
void
gnu::java::net::PlainSocketImpl::close()
{
  // Avoid races from asynchronous finalization.
  JvSynchronize sync (this);

  // should we use shutdown here? how would that effect so_linger?
  int res = ::closesocket (native_fd);

  if (res == -1)
    {
      // These three errors are not errors according to tests performed
      // on the reference implementation.
      DWORD dwErr = WSAGetLastError();
      if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
        && dwErr != WSAENOTSOCK)
        _Jv_ThrowIOException ();
    }
  // Safe place to reset the file pointer.
  native_fd = -1;
  timeout = 0;
}

// Write a byte to the socket.
void
gnu::java::net::PlainSocketImpl$SocketOutputStream::write(jint b)
{
  jbyte d =(jbyte) b;
  int r = 0;

  while (r != 1)
    {
      r = ::send (this$0->native_fd, (char*) &d, 1, 0);
      if (r == -1)
        {
          DWORD dwErr = WSAGetLastError();
          
          // Reset and ignore our thread's interrupted flag.
          // It's not possible to interrupt these sort of
          // operations on Win32 anyway.
          ::java::lang::Thread::interrupted();

          // Some errors should not cause exceptions.
          if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
            && dwErr != WSAENOTSOCK)
            _Jv_ThrowIOException ();
          break;
        }
    }
}

// Write some bytes to the socket.
void
gnu::java::net::PlainSocketImpl$SocketOutputStream::write(jbyteArray b, 
  jint offset, jint len)
{
  if (! b)
    throw new ::java::lang::NullPointerException;
  if (offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))
    throw new ::java::lang::ArrayIndexOutOfBoundsException;

  jbyte *bytes = elements (b) + offset;
  int written = 0;
  while (len > 0)
    {
      int r = ::send (this$0->native_fd, (char*) bytes, len, 0);

      if (r == -1)
        {
          DWORD dwErr = WSAGetLastError();

          // Reset and ignore our thread's interrupted flag.
          ::java::lang::Thread::interrupted();

          // Some errors should not cause exceptions.
          if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
            && dwErr != WSAENOTSOCK)
            _Jv_ThrowIOException ();
          break;
        }

      written += r;
      len -= r;
      bytes += r;
    }
}

void
gnu::java::net::PlainSocketImpl::sendUrgentData (jint)
{
  throw new ::java::net::SocketException (JvNewStringLatin1 (
    "PlainSocketImpl: sending of urgent data not supported by this socket"));
}

// read() helper
static jint
doRead(int native_fd, void* buf, int count, int timeout)
{
  int r = 0;
  DWORD dwErrorCode = 0;
    // we are forced to declare this here because
    // a call to Thread::interrupted() blanks out
    // WSAGetLastError().

  // FIXME: we unconditionally set SO_RCVTIMEO here
  // because we can't detect whether someone has
  // gone from a non-zero to zero timeout. What we'd
  // really need is a member state variable in addition
  // to timeout
  int nRet= ::setsockopt(native_fd, SOL_SOCKET, SO_RCVTIMEO,
    (char*)&timeout, sizeof(timeout));
  if (nRet != NO_ERROR)
  {
    dwErrorCode = WSAGetLastError ();
    goto error;
  }
  
  r = ::recv (native_fd, (char*) buf, count, 0);

  if (r == 0)
    return -1;

  dwErrorCode = WSAGetLastError ();
    // save WSAGetLastError() before calling Thread.interrupted()
  
  // Reset and ignore our thread's interrupted flag.
  ::java::lang::Thread::interrupted();
  
  if (r == -1)
    {
error:
      // Some errors cause us to return end of stream...
      if (dwErrorCode == WSAENOTCONN)
        return -1;

      // Other errors need to be signalled.
      if (dwErrorCode == WSAETIMEDOUT)
        throw new ::java::net::SocketTimeoutException
          (JvNewStringUTF ("Read timed out") );
      else
        _Jv_ThrowIOException (dwErrorCode);
    }
    
   return r;
}

// Read a single byte from the socket.
jint
gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
{
  jbyte b;
  doRead(this$0->native_fd, &b, 1, this$0->timeout);
  return b & 0xFF;
}

// Read count bytes into the buffer, starting at offset.
jint
gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer,
  jint offset, jint count)
{
  // If zero bytes were requested, short circuit so that recv
  // doesn't signal EOF.
  if (count == 0)
    return 0;

  if (! buffer)
    throw new ::java::lang::NullPointerException;

  jsize bsize = JvGetArrayLength (buffer);

  if (offset < 0 || count < 0 || offset + count > bsize)
    throw new ::java::lang::ArrayIndexOutOfBoundsException;

  jbyte *bytes = elements (buffer) + offset;

  // Read the socket.
  return doRead(this$0->native_fd, bytes, count, this$0->timeout);
}

// How many bytes are available?
jint
gnu::java::net::PlainSocketImpl::available(void)
{
  unsigned long num = 0;

  if (::ioctlsocket (native_fd, FIONREAD, &num) == SOCKET_ERROR)
    _Jv_ThrowIOException ();

  return (jint) num;
}

void
gnu::java::net::PlainSocketImpl::setOption (jint optID, ::java::lang::Object *value)
{
  int val;
  socklen_t val_len = sizeof (val);

  if (native_fd < 0)
    throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed"));

  if (_Jv_IsInstanceOf (value, &::java::lang::Boolean::class$))
    {
      ::java::lang::Boolean *boolobj =
        static_cast< ::java::lang::Boolean *> (value);
      if (boolobj->booleanValue())
        val = 1;
      else
        {
          if (optID == _Jv_SO_LINGER_)
            val = -1;
          else
            val = 0;
        }
    }
  else if (_Jv_IsInstanceOf (value, &::java::lang::Integer::class$))
    {
      ::java::lang::Integer *intobj =
        static_cast< ::java::lang::Integer *> (value);
      val = (int) intobj->intValue();
    }
  else
    {
      throw new ::java::lang::IllegalArgumentException (
        JvNewStringLatin1 ("`value' must be Boolean or Integer"));
    }

  switch (optID)
    {
      case _Jv_TCP_NODELAY_ :
        if (::setsockopt (native_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
                          val_len) == SOCKET_ERROR)
          goto error;
        return;

      case _Jv_SO_KEEPALIVE_ :
        if (::setsockopt (native_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
                          val_len) == SOCKET_ERROR)
          goto error;
        break;

      case _Jv_SO_BROADCAST_ :
        throw new ::java::net::SocketException
          (JvNewStringUTF ("SO_BROADCAST not valid for TCP"));
        break;

      case _Jv_SO_OOBINLINE_ :
        if (::setsockopt (native_fd, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
                          val_len) == SOCKET_ERROR)
          goto error;
        break;

      case _Jv_SO_LINGER_ :
        struct linger l_val;
        l_val.l_onoff = (val != -1);
        l_val.l_linger = val;

        if (::setsockopt (native_fd, SOL_SOCKET, SO_LINGER, (char *) &l_val,
                          sizeof(l_val)) == SOCKET_ERROR)
          goto error;
        return;

      case _Jv_SO_SNDBUF_ :
      case _Jv_SO_RCVBUF_ :
        int opt;
        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
        if (::setsockopt (native_fd, SOL_SOCKET, opt, (char *) &val,
                          val_len) == SOCKET_ERROR)
          goto error;
        return;

      case _Jv_SO_BINDADDR_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_BINDADDR: read only option"));
        return;

      case _Jv_IP_MULTICAST_IF_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP"));
        return;

      case _Jv_IP_MULTICAST_IF2_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
        break;

      case _Jv_IP_MULTICAST_LOOP_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
        break;

      case _Jv_IP_TOS_ :
        if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
                          val_len) == SOCKET_ERROR)
          goto error;
        break;

      case _Jv_SO_REUSEADDR_ :
        throw new ::java::net::SocketException (
          JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
        return;

      case _Jv_SO_TIMEOUT_ :
        timeout = val;
        return;

      default :
        WSASetLastError (WSAENOPROTOOPT);
    }

error:
  _Jv_ThrowSocketException ();
}

::java::lang::Object *
gnu::java::net::PlainSocketImpl::getOption (jint optID)
{
  int val;
  socklen_t val_len = sizeof(val);
  union SockAddr u;
  socklen_t addrlen = sizeof(u);
  struct linger l_val;
  socklen_t l_val_len = sizeof(l_val);

  switch (optID)
    {
    case _Jv_TCP_NODELAY_ :
      if (::getsockopt (native_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
                        &val_len) == SOCKET_ERROR)
        goto error;
      else
        return new ::java::lang::Boolean (val != 0);
      break;

    case _Jv_SO_LINGER_ :
      if (::getsockopt (native_fd, SOL_SOCKET, SO_LINGER, (char *) &l_val,
                        &l_val_len) == SOCKET_ERROR)
        goto error;

      if (l_val.l_onoff)
        return new ::java::lang::Integer (l_val.l_linger);
      else
        return new ::java::lang::Boolean ((jboolean)false);
      break;

    case _Jv_SO_KEEPALIVE_ :
      if (::getsockopt (native_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
                        &val_len) == SOCKET_ERROR)
        goto error;
      else
        return new ::java::lang::Boolean (val != 0);

    case _Jv_SO_BROADCAST_ :
      if (::getsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
                        &val_len) == SOCKET_ERROR)
        goto error;
      return new ::java::lang::Boolean ((jboolean)val);

    case _Jv_SO_OOBINLINE_ :
      if (::getsockopt (native_fd, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
                        &val_len) == SOCKET_ERROR)
        goto error;
      return new ::java::lang::Boolean ((jboolean)val);

    case _Jv_SO_RCVBUF_ :
    case _Jv_SO_SNDBUF_ :
      int opt;
      optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
      if (::getsockopt (native_fd, SOL_SOCKET, opt, (char *) &val,
                        &val_len) == SOCKET_ERROR)
        goto error;
      else
        return new ::java::lang::Integer (val);
      break;
    case _Jv_SO_BINDADDR_:
      // cache the local address
      if (localAddress == NULL)
        {
          jbyteArray laddr;

          if (::getsockname (native_fd, (sockaddr*) &u,
                             &addrlen) == SOCKET_ERROR)
            goto error;

          if (u.address.sin_family == AF_INET)
            {
              laddr = JvNewByteArray (4);
              memcpy (elements (laddr), &u.address.sin_addr, 4);
            }
#ifdef HAVE_INET6
          else if (u.address.sin_family == AF_INET6)
            {
              laddr = JvNewByteArray (16);
              memcpy (elements (laddr), &u.address6.sin6_addr, 16);
            }
#endif
          else
            throw new ::java::net::SocketException
              (JvNewStringUTF ("invalid family"));
          localAddress = ::java::net::InetAddress::getByAddress (laddr);
        }

      return localAddress;
      break;
    case _Jv_IP_MULTICAST_IF_ :
      throw new ::java::net::SocketException
        (JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP"));
      break;

    case _Jv_IP_MULTICAST_IF2_ :
      throw new ::java::net::SocketException
        (JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
      break;

    case _Jv_IP_MULTICAST_LOOP_ :
      throw new ::java::net::SocketException
        (JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
      break;

    case _Jv_IP_TOS_ :
      if (::getsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
                        &val_len) == SOCKET_ERROR)
        goto error;
      return new ::java::lang::Integer (val);
      break;

    case _Jv_SO_REUSEADDR_ :
      throw new ::java::net::SocketException
        (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
      break;

    case _Jv_SO_TIMEOUT_ :
      return new ::java::lang::Integer (timeout);
      break;

    default :
      WSASetLastError (WSAENOPROTOOPT);
    }

error:
  _Jv_ThrowSocketException ();
  return 0;
    // we should never get here
}

void
gnu::java::net::PlainSocketImpl::shutdownInput (void)
{
  if (::shutdown (native_fd, 0))
    _Jv_ThrowSocketException ();
}

void
gnu::java::net::PlainSocketImpl::shutdownOutput (void)
{
  if (::shutdown (native_fd, 1))
    _Jv_ThrowSocketException ();
}
