/*
 *  Copyright 2004 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 "rtc_base/async_udp_socket.h"

#include <cstdint>
#include <deque>
#include <memory>
#include <utility>

#include "api/environment/environment.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/mock_socket.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/virtual_socket_server.h"
#include "system_wrappers/include/clock.h"
#include "test/create_test_environment.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {

using ::testing::_;
using ::testing::MockFunction;
using ::testing::NotNull;

TEST(AsyncUDPSocketTest, SetSocketOptionIfEctChange) {
  const SocketAddress kAddr("22.22.22.22", 0);
  VirtualSocketServer socket_server;
  std::unique_ptr<AsyncUDPSocket> udp_socket =
      AsyncUDPSocket::Create(CreateTestEnvironment(), kAddr, socket_server);
  ASSERT_THAT(udp_socket, NotNull());

  int ect = 0;
  udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
  ASSERT_EQ(ect, 0);

  uint8_t buffer[] = "hello";
  AsyncSocketPacketOptions packet_options;
  packet_options.ect_1 = false;
  udp_socket->SendTo(buffer, 5, kAddr, packet_options);
  udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
  EXPECT_EQ(ect, 0);

  packet_options.ect_1 = true;
  udp_socket->SendTo(buffer, 5, kAddr, packet_options);
  udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
  EXPECT_EQ(ect, 1);

  packet_options.ect_1 = false;
  udp_socket->SendTo(buffer, 5, kAddr, packet_options);
  udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
  EXPECT_EQ(ect, 0);
}

TEST(AsyncUDPSocketTest, ArrivalTimeStampCanBeBeforeCurrentTime) {
  SimulatedClock webrtc_clock(Timestamp::Seconds(456));
  Environment env = CreateTestEnvironment({.time = &webrtc_clock});
  std::unique_ptr<MockSocket> socket = std::make_unique<MockSocket>();
  MockSocket* socket_ptr = socket.get();
  AsyncUDPSocket async_socket(env, std::move(socket));
  testing::MockFunction<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
      received_packet_callback;
  async_socket.RegisterReceivedPacketCallback(
      received_packet_callback.AsStdFunction());

  const Timestamp kSocketEpoch = Timestamp::Seconds(123);
  EXPECT_CALL(*socket_ptr, RecvFrom(_))
      .WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
        buffer.payload = "hello";
        buffer.arrival_time = kSocketEpoch;
        return buffer.payload.size();
      });
  EXPECT_CALL(received_packet_callback, Call)
      .WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
        EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
      });
  socket_ptr->SignalReadEvent(socket_ptr);

  // Let 10ms pass until next read event.
  webrtc_clock.AdvanceTime(TimeDelta::Millis(10));

  EXPECT_CALL(*socket_ptr, RecvFrom(_))
      .WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
        buffer.payload = "hello";
        // But only 5 ms has passed since the last received packet.
        buffer.arrival_time = kSocketEpoch + TimeDelta::Millis(5);
        return buffer.payload.size();
      });
  EXPECT_CALL(received_packet_callback, Call)
      .WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
        EXPECT_EQ(packet.arrival_time(),
                  webrtc_clock.CurrentTime() - TimeDelta::Millis(5));
      });
  socket_ptr->SignalReadEvent(socket_ptr);
}

TEST(AsyncUDPSocketTest, InitiallyBufferedPacketsGetSameArrivalTime) {
  SimulatedClock webrtc_clock(Timestamp::Seconds(456));
  Environment env = CreateTestEnvironment({.time = &webrtc_clock});
  std::unique_ptr<MockSocket> socket = std::make_unique<MockSocket>();
  MockSocket* socket_ptr = socket.get();
  AsyncUDPSocket async_socket(env, std::move(socket));
  testing::MockFunction<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
      received_packet_callback;
  async_socket.RegisterReceivedPacketCallback(
      received_packet_callback.AsStdFunction());

  // Simulate that three packets are received with some time delta.
  const Timestamp kSocketEpoch = Timestamp::Seconds(123);
  std::deque<Timestamp> socket_arrival_times = {
      kSocketEpoch, kSocketEpoch + TimeDelta::Millis(10),
      kSocketEpoch + TimeDelta::Millis(20)};

  EXPECT_CALL(*socket_ptr, RecvFrom(_))
      .Times(3)
      .WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
        buffer.payload = "hello";
        buffer.arrival_time = socket_arrival_times.front();
        socket_arrival_times.pop_front();
        return buffer.payload.size();
      });

  EXPECT_CALL(received_packet_callback, Call)
      .Times(3)
      .WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
        // Despite the packets being received at different times, They all have
        // the same timestamp.
        EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
      });
  // But assume, CPU is blocked and can not read the packet at the pace they
  // arrive. Instead they are read one after each other a bit later.
  socket_ptr->SignalReadEvent(socket_ptr);
  socket_ptr->SignalReadEvent(socket_ptr);
  socket_ptr->SignalReadEvent(socket_ptr);
}

TEST(AsyncUDPSocketTest, ArrivalTimeStampCanNotBeAfterCurrentTime) {
  SimulatedClock webrtc_clock(Timestamp::Seconds(456));
  Environment env = CreateTestEnvironment({.time = &webrtc_clock});
  std::unique_ptr<MockSocket> socket = std::make_unique<MockSocket>();
  MockSocket* socket_ptr = socket.get();
  AsyncUDPSocket async_socket(env, std::move(socket));
  testing::MockFunction<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
      received_packet_callback;
  async_socket.RegisterReceivedPacketCallback(
      received_packet_callback.AsStdFunction());

  const Timestamp kSocketEpoch = Timestamp::Seconds(123);
  EXPECT_CALL(*socket_ptr, RecvFrom(_))
      .WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
        buffer.payload = "hello";
        buffer.arrival_time = kSocketEpoch;
        return buffer.payload.size();
      });
  EXPECT_CALL(received_packet_callback, Call)
      .WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
        EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
      });
  socket_ptr->SignalReadEvent(socket_ptr);

  // Let 10ms pass until next read event.
  webrtc_clock.AdvanceTime(TimeDelta::Millis(10));

  EXPECT_CALL(*socket_ptr, RecvFrom(_))
      .WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
        buffer.payload = "hello";
        // But the next packet indicate it is received 25 ms after the previous.
        buffer.arrival_time = kSocketEpoch + TimeDelta::Millis(25);
        return buffer.payload.size();
      });
  EXPECT_CALL(received_packet_callback, Call)
      .WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
        // We still expect the arrival time to be set no later than the current
        // time.
        EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
      });
  socket_ptr->SignalReadEvent(socket_ptr);
}

}  // namespace webrtc
