/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/test/channel_transport/udp_socket_posix.h"

#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/test/channel_transport/udp_socket_manager_wrapper.h"
#include "webrtc/test/channel_transport/udp_socket_wrapper.h"

namespace webrtc {
namespace test {
UdpSocketPosix::UdpSocketPosix(const int32_t id, UdpSocketManager* mgr,
                               bool ipV6Enable) : _id(id)
{
    WEBRTC_TRACE(kTraceMemory, kTraceTransport, id,
                 "UdpSocketPosix::UdpSocketPosix()");

    _wantsIncoming = false;
    _mgr = mgr;

    _obj = NULL;
    _incomingCb = NULL;
    _readyForDeletionCond = ConditionVariableWrapper::CreateConditionVariable();
    _closeBlockingCompletedCond =
        ConditionVariableWrapper::CreateConditionVariable();
    _cs = CriticalSectionWrapper::CreateCriticalSection();
    _readyForDeletion = false;
    _closeBlockingActive = false;
    _closeBlockingCompleted= false;
    if(ipV6Enable)
    {
        _socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    }
    else {
        _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    }

    // Set socket to nonblocking mode.
    int enable_non_blocking = 1;
    if(ioctl(_socket, FIONBIO, &enable_non_blocking) == -1)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceTransport, id,
                     "Failed to make socket nonblocking");
    }
    // Enable close on fork for file descriptor so that it will not block until
    // forked process terminates.
    if(fcntl(_socket, F_SETFD, FD_CLOEXEC) == -1)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceTransport, id,
                     "Failed to set FD_CLOEXEC for socket");
    }
}

UdpSocketPosix::~UdpSocketPosix()
{
    if(_socket != INVALID_SOCKET)
    {
        close(_socket);
        _socket = INVALID_SOCKET;
    }
    if(_readyForDeletionCond)
    {
        delete _readyForDeletionCond;
    }

    if(_closeBlockingCompletedCond)
    {
        delete _closeBlockingCompletedCond;
    }

    if(_cs)
    {
        delete _cs;
    }
}

bool UdpSocketPosix::SetCallback(CallbackObj obj, IncomingSocketCallback cb)
{
    _obj = obj;
    _incomingCb = cb;

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocketPosix(%p)::SetCallback", this);

    if (_mgr->AddSocket(this))
      {
        WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                     "UdpSocketPosix(%p)::SetCallback socket added to manager",
                     this);
        return true;   // socket is now ready for action
      }

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocketPosix(%p)::SetCallback error adding me to mgr",
                 this);
    return false;
}

bool UdpSocketPosix::SetSockopt(int32_t level, int32_t optname,
                                const int8_t* optval, int32_t optlen)
{
   if(0 == setsockopt(_socket, level, optname, optval, optlen ))
   {
       return true;
   }

   WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                "UdpSocketPosix::SetSockopt(), error:%d", errno);
   return false;
}

int32_t UdpSocketPosix::SetTOS(int32_t serviceType)
{
    if (SetSockopt(IPPROTO_IP, IP_TOS ,(int8_t*)&serviceType ,4) != 0)
    {
        return -1;
    }
    return 0;
}

bool UdpSocketPosix::Bind(const SocketAddress& name)
{
    int size = sizeof(sockaddr);
    if (0 == bind(_socket, reinterpret_cast<const sockaddr*>(&name),size))
    {
        return true;
    }
    WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                 "UdpSocketPosix::Bind() error: %d", errno);
    return false;
}

int32_t UdpSocketPosix::SendTo(const int8_t* buf, size_t len,
                               const SocketAddress& to)
{
    int size = sizeof(sockaddr);
    int retVal = sendto(_socket,buf, len, 0,
                        reinterpret_cast<const sockaddr*>(&to), size);
    if(retVal == SOCKET_ERROR)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocketPosix::SendTo() error: %d", errno);
    }

    return retVal;
}

SOCKET UdpSocketPosix::GetFd() { return _socket; }

bool UdpSocketPosix::ValidHandle()
{
    return _socket != INVALID_SOCKET;
}

bool UdpSocketPosix::SetQos(int32_t /*serviceType*/,
                            int32_t /*tokenRate*/,
                            int32_t /*bucketSize*/,
                            int32_t /*peekBandwith*/,
                            int32_t /*minPolicedSize*/,
                            int32_t /*maxSduSize*/,
                            const SocketAddress& /*stRemName*/,
                            int32_t /*overrideDSCP*/) {
  return false;
}

void UdpSocketPosix::HasIncoming()
{
    // replace 2048 with a mcro define and figure out
    // where 2048 comes from
    int8_t buf[2048];
    int retval;
    SocketAddress from;
#if defined(WEBRTC_MAC)
    sockaddr sockaddrfrom;
    memset(&from, 0, sizeof(from));
    memset(&sockaddrfrom, 0, sizeof(sockaddrfrom));
    socklen_t fromlen = sizeof(sockaddrfrom);
#else
    memset(&from, 0, sizeof(from));
    socklen_t fromlen = sizeof(from);
#endif

#if defined(WEBRTC_MAC)
        retval = recvfrom(_socket,buf, sizeof(buf), 0,
                          reinterpret_cast<sockaddr*>(&sockaddrfrom), &fromlen);
        memcpy(&from, &sockaddrfrom, fromlen);
        from._sockaddr_storage.sin_family = sockaddrfrom.sa_family;
#else
        retval = recvfrom(_socket,buf, sizeof(buf), 0,
                          reinterpret_cast<sockaddr*>(&from), &fromlen);
#endif

    switch(retval)
    {
    case 0:
        // The peer has performed an orderly shutdown.
        break;
    case SOCKET_ERROR:
        break;
    default:
        if (_wantsIncoming && _incomingCb)
        {
          _incomingCb(_obj, buf, retval, &from);
        }
        break;
    }
}

bool UdpSocketPosix::WantsIncoming() { return _wantsIncoming; }

void UdpSocketPosix::CloseBlocking()
{
    _cs->Enter();
    _closeBlockingActive = true;
    if(!CleanUp())
    {
        _closeBlockingActive = false;
        _cs->Leave();
        return;
    }

    while(!_readyForDeletion)
    {
        _readyForDeletionCond->SleepCS(*_cs);
    }
    _closeBlockingCompleted = true;
    _closeBlockingCompletedCond->Wake();
    _cs->Leave();
}

void UdpSocketPosix::ReadyForDeletion()
{
    _cs->Enter();
    if(!_closeBlockingActive)
    {
        _cs->Leave();
        return;
    }
    close(_socket);
    _socket = INVALID_SOCKET;
    _readyForDeletion = true;
    _readyForDeletionCond->Wake();
    while(!_closeBlockingCompleted)
    {
        _closeBlockingCompletedCond->SleepCS(*_cs);
    }
    _cs->Leave();
}

bool UdpSocketPosix::CleanUp()
{
    _wantsIncoming = false;

    if (_socket == INVALID_SOCKET)
    {
        return false;
    }

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "calling UdpSocketManager::RemoveSocket()...");
    _mgr->RemoveSocket(this);
    // After this, the socket should may be or will be as deleted. Return
    // immediately.
    return true;
}

}  // namespace test
}  // namespace webrtc
