//
// detail/impl/winrt_ssocket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP
#define ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include "asio/detail/config.hpp"

#if defined(ASIO_WINDOWS_RUNTIME)

#include <cstring>
#include "asio/detail/winrt_ssocket_service_base.hpp"
#include "asio/detail/winrt_async_op.hpp"
#include "asio/detail/winrt_utils.hpp"

#include "asio/detail/push_options.hpp"

namespace asio {
namespace detail {

winrt_ssocket_service_base::winrt_ssocket_service_base(
    asio::io_context& io_context)
  : io_context_(use_service<io_context_impl>(io_context)),
    async_manager_(use_service<winrt_async_manager>(io_context)),
    mutex_(),
    impl_list_(0)
{
}

void winrt_ssocket_service_base::base_shutdown()
{
  // Close all implementations, causing all operations to complete.
  asio::detail::mutex::scoped_lock lock(mutex_);
  base_implementation_type* impl = impl_list_;
  while (impl)
  {
    asio::error_code ignored_ec;
    close(*impl, ignored_ec);
    impl = impl->next_;
  }
}

void winrt_ssocket_service_base::construct(
    winrt_ssocket_service_base::base_implementation_type& impl)
{
  // Insert implementation into linked list of all implementations.
  asio::detail::mutex::scoped_lock lock(mutex_);
  impl.next_ = impl_list_;
  impl.prev_ = 0;
  if (impl_list_)
    impl_list_->prev_ = &impl;
  impl_list_ = &impl;
}

void winrt_ssocket_service_base::base_move_construct(
    winrt_ssocket_service_base::base_implementation_type& impl,
    winrt_ssocket_service_base::base_implementation_type& other_impl)
{
  impl.socket_ = other_impl.socket_;
  other_impl.socket_ = nullptr;

  // Insert implementation into linked list of all implementations.
  asio::detail::mutex::scoped_lock lock(mutex_);
  impl.next_ = impl_list_;
  impl.prev_ = 0;
  if (impl_list_)
    impl_list_->prev_ = &impl;
  impl_list_ = &impl;
}

void winrt_ssocket_service_base::base_move_assign(
    winrt_ssocket_service_base::base_implementation_type& impl,
    winrt_ssocket_service_base& other_service,
    winrt_ssocket_service_base::base_implementation_type& other_impl)
{
  asio::error_code ignored_ec;
  close(impl, ignored_ec);

  if (this != &other_service)
  {
    // Remove implementation from linked list of all implementations.
    asio::detail::mutex::scoped_lock lock(mutex_);
    if (impl_list_ == &impl)
      impl_list_ = impl.next_;
    if (impl.prev_)
      impl.prev_->next_ = impl.next_;
    if (impl.next_)
      impl.next_->prev_= impl.prev_;
    impl.next_ = 0;
    impl.prev_ = 0;
  }

  impl.socket_ = other_impl.socket_;
  other_impl.socket_ = nullptr;

  if (this != &other_service)
  {
    // Insert implementation into linked list of all implementations.
    asio::detail::mutex::scoped_lock lock(other_service.mutex_);
    impl.next_ = other_service.impl_list_;
    impl.prev_ = 0;
    if (other_service.impl_list_)
      other_service.impl_list_->prev_ = &impl;
    other_service.impl_list_ = &impl;
  }
}

void winrt_ssocket_service_base::destroy(
    winrt_ssocket_service_base::base_implementation_type& impl)
{
  asio::error_code ignored_ec;
  close(impl, ignored_ec);

  // Remove implementation from linked list of all implementations.
  asio::detail::mutex::scoped_lock lock(mutex_);
  if (impl_list_ == &impl)
    impl_list_ = impl.next_;
  if (impl.prev_)
    impl.prev_->next_ = impl.next_;
  if (impl.next_)
    impl.next_->prev_= impl.prev_;
  impl.next_ = 0;
  impl.prev_ = 0;
}

asio::error_code winrt_ssocket_service_base::close(
    winrt_ssocket_service_base::base_implementation_type& impl,
    asio::error_code& ec)
{
  if (impl.socket_)
  {
    delete impl.socket_;
    impl.socket_ = nullptr;
  }

  ec = asio::error_code();
  return ec;
}

std::size_t winrt_ssocket_service_base::do_get_endpoint(
    const base_implementation_type& impl, bool local,
    void* addr, std::size_t addr_len, asio::error_code& ec) const
{
  if (!is_open(impl))
  {
    ec = asio::error::bad_descriptor;
    return addr_len;
  }

  try
  {
    std::string addr_string = winrt_utils::string(local
        ? impl.socket_->Information->LocalAddress->CanonicalName
        : impl.socket_->Information->RemoteAddress->CanonicalName);
    unsigned short port = winrt_utils::integer(local
        ? impl.socket_->Information->LocalPort
        : impl.socket_->Information->RemotePort);
    unsigned long scope = 0;

    switch (reinterpret_cast<const socket_addr_type*>(addr)->sa_family)
    {
    case ASIO_OS_DEF(AF_INET):
      if (addr_len < sizeof(sockaddr_in4_type))
      {
        ec = asio::error::invalid_argument;
        return addr_len;
      }
      else
      {
        socket_ops::inet_pton(ASIO_OS_DEF(AF_INET), addr_string.c_str(),
            &reinterpret_cast<sockaddr_in4_type*>(addr)->sin_addr, &scope, ec);
        reinterpret_cast<sockaddr_in4_type*>(addr)->sin_port
          = socket_ops::host_to_network_short(port);
        ec = asio::error_code();
        return sizeof(sockaddr_in4_type);
      }
    case ASIO_OS_DEF(AF_INET6):
      if (addr_len < sizeof(sockaddr_in6_type))
      {
        ec = asio::error::invalid_argument;
        return addr_len;
      }
      else
      {
        socket_ops::inet_pton(ASIO_OS_DEF(AF_INET6), addr_string.c_str(),
            &reinterpret_cast<sockaddr_in6_type*>(addr)->sin6_addr, &scope, ec);
        reinterpret_cast<sockaddr_in6_type*>(addr)->sin6_port
          = socket_ops::host_to_network_short(port);
        ec = asio::error_code();
        return sizeof(sockaddr_in6_type);
      }
    default:
      ec = asio::error::address_family_not_supported;
      return addr_len;
    }
  }
  catch (Platform::Exception^ e)
  {
    ec = asio::error_code(e->HResult,
        asio::system_category());
    return addr_len;
  }
}

asio::error_code winrt_ssocket_service_base::do_set_option(
    winrt_ssocket_service_base::base_implementation_type& impl,
    int level, int optname, const void* optval,
    std::size_t optlen, asio::error_code& ec)
{
  if (!is_open(impl))
  {
    ec = asio::error::bad_descriptor;
    return ec;
  }

  try
  {
    if (level == ASIO_OS_DEF(SOL_SOCKET)
        && optname == ASIO_OS_DEF(SO_KEEPALIVE))
    {
      if (optlen == sizeof(int))
      {
        int value = 0;
        std::memcpy(&value, optval, optlen);
        impl.socket_->Control->KeepAlive = !!value;
        ec = asio::error_code();
      }
      else
      {
        ec = asio::error::invalid_argument;
      }
    }
    else if (level == ASIO_OS_DEF(IPPROTO_TCP)
        && optname == ASIO_OS_DEF(TCP_NODELAY))
    {
      if (optlen == sizeof(int))
      {
        int value = 0;
        std::memcpy(&value, optval, optlen);
        impl.socket_->Control->NoDelay = !!value;
        ec = asio::error_code();
      }
      else
      {
        ec = asio::error::invalid_argument;
      }
    }
    else
    {
      ec = asio::error::invalid_argument;
    }
  }
  catch (Platform::Exception^ e)
  {
    ec = asio::error_code(e->HResult,
        asio::system_category());
  }

  return ec;
}

void winrt_ssocket_service_base::do_get_option(
    const winrt_ssocket_service_base::base_implementation_type& impl,
    int level, int optname, void* optval,
    std::size_t* optlen, asio::error_code& ec) const
{
  if (!is_open(impl))
  {
    ec = asio::error::bad_descriptor;
    return;
  }

  try
  {
    if (level == ASIO_OS_DEF(SOL_SOCKET)
        && optname == ASIO_OS_DEF(SO_KEEPALIVE))
    {
      if (*optlen >= sizeof(int))
      {
        int value = impl.socket_->Control->KeepAlive ? 1 : 0;
        std::memcpy(optval, &value, sizeof(int));
        *optlen = sizeof(int);
        ec = asio::error_code();
      }
      else
      {
        ec = asio::error::invalid_argument;
      }
    }
    else if (level == ASIO_OS_DEF(IPPROTO_TCP)
        && optname == ASIO_OS_DEF(TCP_NODELAY))
    {
      if (*optlen >= sizeof(int))
      {
        int value = impl.socket_->Control->NoDelay ? 1 : 0;
        std::memcpy(optval, &value, sizeof(int));
        *optlen = sizeof(int);
        ec = asio::error_code();
      }
      else
      {
        ec = asio::error::invalid_argument;
      }
    }
    else
    {
      ec = asio::error::invalid_argument;
    }
  }
  catch (Platform::Exception^ e)
  {
    ec = asio::error_code(e->HResult,
        asio::system_category());
  }
}

asio::error_code winrt_ssocket_service_base::do_connect(
    winrt_ssocket_service_base::base_implementation_type& impl,
    const void* addr, asio::error_code& ec)
{
  if (!is_open(impl))
  {
    ec = asio::error::bad_descriptor;
    return ec;
  }

  char addr_string[max_addr_v6_str_len];
  unsigned short port;
  switch (reinterpret_cast<const socket_addr_type*>(addr)->sa_family)
  {
  case ASIO_OS_DEF(AF_INET):
    socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET),
        &reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_addr,
        addr_string, sizeof(addr_string), 0, ec);
    port = socket_ops::network_to_host_short(
        reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_port);
    break;
  case ASIO_OS_DEF(AF_INET6):
    socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET6),
        &reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_addr,
        addr_string, sizeof(addr_string), 0, ec);
    port = socket_ops::network_to_host_short(
        reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_port);
    break;
  default:
    ec = asio::error::address_family_not_supported;
    return ec;
  }

  if (!ec) try
  {
    async_manager_.sync(impl.socket_->ConnectAsync(
          ref new Windows::Networking::HostName(
            winrt_utils::string(addr_string)),
          winrt_utils::string(port)), ec);
  }
  catch (Platform::Exception^ e)
  {
    ec = asio::error_code(e->HResult,
        asio::system_category());
  }

  return ec;
}

void winrt_ssocket_service_base::start_connect_op(
    winrt_ssocket_service_base::base_implementation_type& impl,
    const void* addr, winrt_async_op<void>* op, bool is_continuation)
{
  if (!is_open(impl))
  {
    op->ec_ = asio::error::bad_descriptor;
    io_context_.post_immediate_completion(op, is_continuation);
    return;
  }

  char addr_string[max_addr_v6_str_len];
  unsigned short port = 0;
  switch (reinterpret_cast<const socket_addr_type*>(addr)->sa_family)
  {
  case ASIO_OS_DEF(AF_INET):
    socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET),
        &reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_addr,
        addr_string, sizeof(addr_string), 0, op->ec_);
    port = socket_ops::network_to_host_short(
        reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_port);
    break;
  case ASIO_OS_DEF(AF_INET6):
    socket_ops::inet_ntop(ASIO_OS_DEF(AF_INET6),
        &reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_addr,
        addr_string, sizeof(addr_string), 0, op->ec_);
    port = socket_ops::network_to_host_short(
        reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_port);
    break;
  default:
    op->ec_ = asio::error::address_family_not_supported;
    break;
  }

  if (op->ec_)
  {
    io_context_.post_immediate_completion(op, is_continuation);
    return;
  }

  try
  {
    async_manager_.async(impl.socket_->ConnectAsync(
          ref new Windows::Networking::HostName(
            winrt_utils::string(addr_string)),
          winrt_utils::string(port)), op);
  }
  catch (Platform::Exception^ e)
  {
    op->ec_ = asio::error_code(
        e->HResult, asio::system_category());
    io_context_.post_immediate_completion(op, is_continuation);
  }
}

std::size_t winrt_ssocket_service_base::do_send(
    winrt_ssocket_service_base::base_implementation_type& impl,
    const asio::const_buffer& data,
    socket_base::message_flags flags, asio::error_code& ec)
{
  if (flags)
  {
    ec = asio::error::operation_not_supported;
    return 0;
  }

  if (!is_open(impl))
  {
    ec = asio::error::bad_descriptor;
    return 0;
  }

  try
  {
    buffer_sequence_adapter<asio::const_buffer,
      asio::const_buffers_1> bufs(asio::buffer(data));

    if (bufs.all_empty())
    {
      ec = asio::error_code();
      return 0;
    }

    return async_manager_.sync(
        impl.socket_->OutputStream->WriteAsync(bufs.buffers()[0]), ec);
  }
  catch (Platform::Exception^ e)
  {
    ec = asio::error_code(e->HResult,
        asio::system_category());
    return 0;
  }
}

void winrt_ssocket_service_base::start_send_op(
      winrt_ssocket_service_base::base_implementation_type& impl,
      const asio::const_buffer& data, socket_base::message_flags flags,
      winrt_async_op<unsigned int>* op, bool is_continuation)
{
  if (flags)
  {
    op->ec_ = asio::error::operation_not_supported;
    io_context_.post_immediate_completion(op, is_continuation);
    return;
  }

  if (!is_open(impl))
  {
    op->ec_ = asio::error::bad_descriptor;
    io_context_.post_immediate_completion(op, is_continuation);
    return;
  }

  try
  {
    buffer_sequence_adapter<asio::const_buffer,
        asio::const_buffers_1> bufs(asio::buffer(data));

    if (bufs.all_empty())
    {
      io_context_.post_immediate_completion(op, is_continuation);
      return;
    }

    async_manager_.async(
        impl.socket_->OutputStream->WriteAsync(bufs.buffers()[0]), op);
  }
  catch (Platform::Exception^ e)
  {
    op->ec_ = asio::error_code(e->HResult,
        asio::system_category());
    io_context_.post_immediate_completion(op, is_continuation);
  }
}

std::size_t winrt_ssocket_service_base::do_receive(
    winrt_ssocket_service_base::base_implementation_type& impl,
    const asio::mutable_buffer& data,
    socket_base::message_flags flags, asio::error_code& ec)
{
  if (flags)
  {
    ec = asio::error::operation_not_supported;
    return 0;
  }

  if (!is_open(impl))
  {
    ec = asio::error::bad_descriptor;
    return 0;
  }

  try
  {
    buffer_sequence_adapter<asio::mutable_buffer,
        asio::mutable_buffers_1> bufs(asio::buffer(data));

    if (bufs.all_empty())
    {
      ec = asio::error_code();
      return 0;
    }

    async_manager_.sync(
        impl.socket_->InputStream->ReadAsync(
          bufs.buffers()[0], bufs.buffers()[0]->Capacity,
          Windows::Storage::Streams::InputStreamOptions::Partial), ec);

    std::size_t bytes_transferred = bufs.buffers()[0]->Length;
    if (bytes_transferred == 0 && !ec)
    {
      ec = asio::error::eof;
    }

    return bytes_transferred;
  }
  catch (Platform::Exception^ e)
  {
    ec = asio::error_code(e->HResult,
        asio::system_category());
    return 0;
  }
}

void winrt_ssocket_service_base::start_receive_op(
      winrt_ssocket_service_base::base_implementation_type& impl,
      const asio::mutable_buffer& data, socket_base::message_flags flags,
      winrt_async_op<Windows::Storage::Streams::IBuffer^>* op,
      bool is_continuation)
{
  if (flags)
  {
    op->ec_ = asio::error::operation_not_supported;
    io_context_.post_immediate_completion(op, is_continuation);
    return;
  }

  if (!is_open(impl))
  {
    op->ec_ = asio::error::bad_descriptor;
    io_context_.post_immediate_completion(op, is_continuation);
    return;
  }

  try
  {
    buffer_sequence_adapter<asio::mutable_buffer,
        asio::mutable_buffers_1> bufs(asio::buffer(data));

    if (bufs.all_empty())
    {
      io_context_.post_immediate_completion(op, is_continuation);
      return;
    }

    async_manager_.async(
        impl.socket_->InputStream->ReadAsync(
          bufs.buffers()[0], bufs.buffers()[0]->Capacity,
          Windows::Storage::Streams::InputStreamOptions::Partial), op);
  }
  catch (Platform::Exception^ e)
  {
    op->ec_ = asio::error_code(e->HResult,
        asio::system_category());
    io_context_.post_immediate_completion(op, is_continuation);
  }
}

} // namespace detail
} // namespace asio

#include "asio/detail/pop_options.hpp"

#endif // defined(ASIO_WINDOWS_RUNTIME)

#endif // ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP
