/*
 *  Copyright 2016 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 "p2p/base/udptransport.h"

#include <string>
#include <utility>  // For std::move.

#include "rtc_base/asyncpacketsocket.h"
#include "rtc_base/asyncudpsocket.h"
#include "rtc_base/logging.h"
#include "rtc_base/socketaddress.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_checker.h"

namespace cricket {

UdpTransport::UdpTransport(const std::string& transport_name,
                           std::unique_ptr<rtc::AsyncPacketSocket> socket)
    : transport_name_(transport_name), socket_(std::move(socket)) {
  RTC_DCHECK(socket_);
  socket_->SignalReadPacket.connect(this, &UdpTransport::OnSocketReadPacket);
  socket_->SignalSentPacket.connect(this, &UdpTransport::OnSocketSentPacket);
}

UdpTransport::~UdpTransport() {
  RTC_DCHECK_RUN_ON(&network_thread_checker_);
}

rtc::SocketAddress UdpTransport::GetLocalAddress() const {
  RTC_DCHECK_RUN_ON(&network_thread_checker_);
  return socket_->GetLocalAddress();
}

bool UdpTransport::SetRemoteAddress(const rtc::SocketAddress& addr) {
  RTC_DCHECK_RUN_ON(&network_thread_checker_);
  if (!addr.IsComplete()) {
    LOG(LS_WARNING) << "Remote address not complete.";
    return false;
  }
  // TODO(johan): check for ipv4, other settings.
  bool prev_destination_nil = remote_address_.IsNil();
  remote_address_ = addr;
  // Going from "didn't have destination" to "have destination" or vice versa.
  if (prev_destination_nil != remote_address_.IsNil()) {
    SignalWritableState(this);
    if (prev_destination_nil) {
      SignalReadyToSend(this);
    }
  }
  return true;
}

rtc::SocketAddress UdpTransport::GetRemoteAddress() const {
  RTC_DCHECK_RUN_ON(&network_thread_checker_);
  return remote_address_;
}

std::string UdpTransport::debug_name() const {
  return transport_name_;
}

bool UdpTransport::receiving() const {
  // TODO(johan): Implement method and signal.
  return true;
}

bool UdpTransport::writable() const {
  RTC_DCHECK_RUN_ON(&network_thread_checker_);
  return !remote_address_.IsNil();
}

int UdpTransport::SendPacket(const char* data,
                             size_t len,
                             const rtc::PacketOptions& options,
                             int flags) {
  // No thread_checker in high frequency network function.
  if (remote_address_.IsNil()) {
    LOG(LS_WARNING) << "Remote address not set.";
    send_error_ = ENOTCONN;
    return -1;
  }
  int result =
      socket_->SendTo((const void*)data, len, remote_address_, options);
  if (result <= 0) {
    LOG(LS_VERBOSE) << "SendPacket() " << result;
  }
  return result;
}

int UdpTransport::SetOption(rtc::Socket::Option opt, int value) {
  return 0;
}

int UdpTransport::GetError() {
  return send_error_;
}

rtc::PacketTransportInternal* UdpTransport::GetInternal() {
  return this;
}

void UdpTransport::OnSocketReadPacket(rtc::AsyncPacketSocket* socket,
                                      const char* data,
                                      size_t len,
                                      const rtc::SocketAddress& remote_addr,
                                      const rtc::PacketTime& packet_time) {
  // No thread_checker in high frequency network function.
  SignalReadPacket(this, data, len, packet_time, 0);
}

void UdpTransport::OnSocketSentPacket(rtc::AsyncPacketSocket* socket,
                                      const rtc::SentPacket& packet) {
  RTC_DCHECK_EQ(socket_.get(), socket);
  SignalSentPacket(this, packet);
}

}  // namespace cricket
