/*
 *  Copyright (c) 2019 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 "api/test/network_emulation_manager.h"

#include <utility>

#include "api/units/data_rate.h"
#include "rtc_base/checks.h"
#include "test/network/simulated_network.h"

namespace webrtc {

bool AbslParseFlag(absl::string_view text, TimeMode* mode, std::string* error) {
  if (text == "realtime") {
    *mode = TimeMode::kRealTime;
    return true;
  }
  if (text == "simulated") {
    *mode = TimeMode::kSimulated;
    return true;
  }
  *error =
      "Unknown value for TimeMode enum. Options are 'realtime' or 'simulated'";
  return false;
}

std::string AbslUnparseFlag(TimeMode mode) {
  switch (mode) {
    case TimeMode::kRealTime:
      return "realtime";
    case TimeMode::kSimulated:
      return "simulated";
  }
  RTC_CHECK_NOTREACHED();
  return "unknown";
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::config(
    BuiltInNetworkBehaviorConfig config) {
  config_ = config;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::delay_ms(
    int queue_delay_ms) {
  config_.queue_delay_ms = queue_delay_ms;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity(
    DataRate link_capacity) {
  config_.link_capacity = link_capacity;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_kbps(
    int link_capacity_kbps) {
  if (link_capacity_kbps > 0) {
    config_.link_capacity = DataRate::KilobitsPerSec(link_capacity_kbps);
  } else {
    config_.link_capacity = DataRate::Infinity();
  }
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_Mbps(
    int link_capacity_Mbps) {
  if (link_capacity_Mbps > 0) {
    config_.link_capacity = DataRate::KilobitsPerSec(link_capacity_Mbps * 1000);
  } else {
    config_.link_capacity = DataRate::Infinity();
  }
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::loss(double loss_rate) {
  config_.loss_percent = loss_rate * 100;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::packet_queue_length(
    int max_queue_length_in_packets) {
  config_.queue_length_packets = max_queue_length_in_packets;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::
    delay_standard_deviation_ms(int delay_standard_deviation_ms) {
  config_.delay_standard_deviation_ms = delay_standard_deviation_ms;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::allow_reordering() {
  config_.allow_reordering = true;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::avg_burst_loss_length(
    int avg_burst_loss_length) {
  config_.avg_burst_loss_length = avg_burst_loss_length;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode::Builder&
NetworkEmulationManager::SimulatedNetworkNode::Builder::packet_overhead(
    int packet_overhead) {
  config_.packet_overhead = packet_overhead;
  return *this;
}

NetworkEmulationManager::SimulatedNetworkNode
NetworkEmulationManager::SimulatedNetworkNode::Builder::Build(
    uint64_t random_seed) const {
  RTC_CHECK(net_);
  return Build(net_, random_seed);
}

NetworkEmulationManager::SimulatedNetworkNode
NetworkEmulationManager::SimulatedNetworkNode::Builder::Build(
    NetworkEmulationManager* net,
    uint64_t random_seed) const {
  RTC_CHECK(net);
  RTC_CHECK(net_ == nullptr || net_ == net);
  SimulatedNetworkNode res;
  auto behavior = std::make_unique<SimulatedNetwork>(config_, random_seed);
  res.simulation = behavior.get();
  res.node = net->CreateEmulatedNode(std::move(behavior));
  return res;
}

std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>
NetworkEmulationManager::CreateEndpointPairWithTwoWayRoutes(
    const BuiltInNetworkBehaviorConfig& config) {
  auto* alice_node = CreateEmulatedNode(config);
  auto* bob_node = CreateEmulatedNode(config);

  auto* alice_endpoint = CreateEndpoint(EmulatedEndpointConfig());
  auto* bob_endpoint = CreateEndpoint(EmulatedEndpointConfig());

  CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
  CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);

  return {
      CreateEmulatedNetworkManagerInterface({alice_endpoint}),
      CreateEmulatedNetworkManagerInterface({bob_endpoint}),
  };
}
}  // namespace webrtc
