// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// Licensed 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 "starboard/common/socket.h"

#include <iomanip>

#include "starboard/common/log.h"
#include "starboard/configuration.h"

namespace starboard {

SbSocketAddress GetUnspecifiedAddress(SbSocketAddressType address_type,
                                      int port) {
  SbSocketAddress address = {};
  address.type = address_type;
  address.port = port;
  return address;
}

bool GetLocalhostAddress(SbSocketAddressType address_type,
                         int port,
                         SbSocketAddress* address) {
  if (address_type != kSbSocketAddressTypeIpv4 &&
      address_type != kSbSocketAddressTypeIpv6) {
    SB_LOG(ERROR) << __FUNCTION__ << ": unknown address type: " << address_type;
    return false;
  }
  *address = GetUnspecifiedAddress(address_type, port);
  switch (address_type) {
    case kSbSocketAddressTypeIpv4:
      address->address[0] = 127;
      address->address[3] = 1;
      break;
    case kSbSocketAddressTypeIpv6:
      address->address[15] = 1;
      break;
  }

  return true;
}

Socket::Socket(SbSocketAddressType address_type, SbSocketProtocol protocol)
    : socket_(SbSocketCreate(address_type, protocol)) {}

Socket::Socket(SbSocketAddressType address_type)
    : socket_(SbSocketCreate(address_type, kSbSocketProtocolTcp)) {}

Socket::Socket(SbSocketProtocol protocol)
    : socket_(SbSocketCreate(kSbSocketAddressTypeIpv4, protocol)) {}

Socket::Socket()
    : socket_(SbSocketCreate(kSbSocketAddressTypeIpv4, kSbSocketProtocolTcp)) {}

Socket::~Socket() {
  SbSocketDestroy(socket_);
}

bool Socket::IsValid() {
  return SbSocketIsValid(socket_);
}

SbSocketError Socket::Connect(const SbSocketAddress* address) {
  return SbSocketConnect(socket_, address);
}

SbSocketError Socket::Bind(const SbSocketAddress* local_address) {
  return SbSocketBind(socket_, local_address);
}

SbSocketError Socket::Listen() {
  return SbSocketListen(socket_);
}

Socket* Socket::Accept() {
  SbSocket accepted_socket = SbSocketAccept(socket_);
  if (SbSocketIsValid(accepted_socket)) {
    return new Socket(accepted_socket);
  }

  return NULL;
}

bool Socket::IsConnected() {
  return SbSocketIsConnected(socket_);
}

bool Socket::IsConnectedAndIdle() {
  return SbSocketIsConnectedAndIdle(socket_);
}

bool Socket::IsPending() {
  return GetLastError() == kSbSocketPending;
}

SbSocketError Socket::GetLastError() {
  return SbSocketGetLastError(socket_);
}

void Socket::ClearLastError() {
  SbSocketClearLastError(socket_);
}

int Socket::ReceiveFrom(char* out_data,
                        int data_size,
                        SbSocketAddress* out_source) {
  return SbSocketReceiveFrom(socket_, out_data, data_size, out_source);
}

int Socket::SendTo(const char* data,
                   int data_size,
                   const SbSocketAddress* destination) {
  return SbSocketSendTo(socket_, data, data_size, destination);
}

bool Socket::GetLocalAddress(SbSocketAddress* out_address) {
  return SbSocketGetLocalAddress(socket_, out_address);
}

bool Socket::SetBroadcast(bool value) {
  return SbSocketSetBroadcast(socket_, value);
}

bool Socket::SetReuseAddress(bool value) {
  return SbSocketSetReuseAddress(socket_, value);
}

bool Socket::SetReceiveBufferSize(int32_t size) {
  return SbSocketSetReceiveBufferSize(socket_, size);
}

bool Socket::SetSendBufferSize(int32_t size) {
  return SbSocketSetSendBufferSize(socket_, size);
}

bool Socket::SetTcpKeepAlive(bool value, int64_t period) {
  return SbSocketSetTcpKeepAlive(socket_, value, period);
}

bool Socket::SetTcpNoDelay(bool value) {
  return SbSocketSetTcpNoDelay(socket_, value);
}

bool Socket::SetTcpWindowScaling(bool value) {
  return SbSocketSetTcpWindowScaling(socket_, value);
}

bool Socket::JoinMulticastGroup(const SbSocketAddress* address) {
  return SbSocketJoinMulticastGroup(socket_, address);
}

SbSocket Socket::socket() {
  return socket_;
}

Socket::Socket(SbSocket socket) : socket_(socket) {}

}  // namespace starboard

std::ostream& operator<<(std::ostream& os, const SbSocketAddress& address) {
  if (address.type == kSbSocketAddressTypeIpv6) {
    os << std::hex << "[";
    const uint16_t* fields = reinterpret_cast<const uint16_t*>(address.address);
    int i = 0;
    while (fields[i] == 0) {
      if (i == 0) {
        os << ":";
      }
      ++i;
      if (i == 8) {
        os << ":";
      }
    }
    for (; i < 8; ++i) {
      if (i != 0) {
        os << ":";
      }
#if SB_IS(LITTLE_ENDIAN)
      const uint8_t* fields8 = reinterpret_cast<const uint8_t*>(&fields[i]);
      const uint16_t value = static_cast<uint16_t>(fields8[0]) * 256 |
                             static_cast<uint16_t>(fields8[1]);
      os << value;
#else
      os << fields[i];
#endif
    }
    os << "]" << std::dec;
  } else {
    for (int i = 0; i < 4; ++i) {
      if (i != 0) {
        os << ".";
      }
      os << static_cast<int>(address.address[i]);
    }
  }
  os << ":" << address.port;
  return os;
}
