// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// moqt_simulator simulates the behavior of MoQ Transport under various network
// conditions and application settings.

#include <cstdint>
#include <iostream>
#include <string>

#include "absl/strings/ascii.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "quiche/quic/core/quic_bandwidth.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/moqt/moqt_priority.h"
#include "quiche/quic/moqt/test_tools/moqt_simulator.h"
#include "quiche/common/platform/api/quiche_command_line_flags.h"

namespace {

using ::quic::QuicBandwidth;
using ::quic::QuicByteCount;
using ::quic::QuicTimeDelta;

}  // namespace

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    uint64_t, bandwidth,
    moqt::test::SimulationParameters().bandwidth.ToKBitsPerSecond(),
    "Bandwidth of the simulated link, in kilobits per second.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    uint64_t, bitrate,
    moqt::test::SimulationParameters().bitrate.ToKBitsPerSecond(),
    "Initial bitrate of the simulated media.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    absl::Duration, deadline,
    moqt::test::SimulationParameters().deadline.ToAbsl(),
    "Frame delivery deadline (used for measurement only).");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    absl::Duration, duration,
    moqt::test::SimulationParameters().duration.ToAbsl(),
    "Duration of the simulation");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, delivery_order, "desc",
    "Delivery order used for the MoQT track simulated ('asc' or 'desc').");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, bitrate_adaptation, true,
    "Whether track payload's bitrate can be adjusted.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(absl::Duration, delivery_timeout,
                                absl::InfiniteDuration(),
                                "Delivery timeout for the subscription.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, alternative_timeout, false,
                                "Use alternative delivery timeout design.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    float, packet_loss_rate,
    moqt::test::SimulationParameters().packet_loss_rate,
    "Adds additional packet loss at the publisher-to-subscriber direction, "
    "specified as a fraction.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    absl::Duration, blackhole_duration,
    moqt::test::SimulationParameters().blackhole_duration.ToAbsl(),
    "If non-zero, makes the traffic disappear in the middle of the connection "
    "for the specified duration.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    quic::QuicByteCount, aggregation_threshold,
    moqt::test::SimulationParameters().aggregation_threshold,
    "If non-zero, enables packet aggregation with the specified threshold (the "
    "packets sent by publisher will be delayed until the specified number is "
    "present).");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    absl::Duration, aggregation_timeout,
    moqt::test::SimulationParameters().aggregation_timeout.ToAbsl(),
    "Sets the timeout for packet aggregation; if zero, this will be set to the "
    "quarter of min RTT.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    absl::Duration, group_duration, absl::ZeroDuration(),
    "If non-zero, sets the group size to match the requested duration");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, output_format, "",
    R"(If non-empty, instead of the usual human-readable format,
the tool will output the raw numbers from the simulation, formatted as
descrbied by the parameter.

Supported format keys:
* {on_time_fraction} -- fraction of objects that arrived on time
* {late_fraction} -- fraction of objects that arrived late
* {missing_fraction} -- fraction of objects that never arrived)");

int main(int argc, char** argv) {
  moqt::test::SimulationParameters parameters;
  quiche::QuicheParseCommandLineFlags("moqt_simulator", argc, argv);
  parameters.bandwidth = quic::QuicBandwidth::FromKBitsPerSecond(
      quiche::GetQuicheCommandLineFlag(FLAGS_bandwidth));
  parameters.bitrate = quic::QuicBandwidth::FromKBitsPerSecond(
      quiche::GetQuicheCommandLineFlag(FLAGS_bitrate));
  parameters.deadline =
      quic::QuicTimeDelta(quiche::GetQuicheCommandLineFlag(FLAGS_deadline));
  parameters.duration =
      quic::QuicTimeDelta(quiche::GetQuicheCommandLineFlag(FLAGS_duration));
  parameters.bitrate_adaptation =
      quiche::GetQuicheCommandLineFlag(FLAGS_bitrate_adaptation);
  parameters.delivery_timeout = quic::QuicTimeDelta(
      quiche::GetQuicheCommandLineFlag(FLAGS_delivery_timeout));
  parameters.packet_loss_rate =
      quiche::GetQuicheCommandLineFlag(FLAGS_packet_loss_rate);
  parameters.alternative_timeout =
      quiche::GetQuicheCommandLineFlag(FLAGS_alternative_timeout);
  parameters.blackhole_duration = quic::QuicTimeDelta(
      quiche::GetQuicheCommandLineFlag(FLAGS_blackhole_duration));
  parameters.aggregation_threshold =
      quiche::GetQuicheCommandLineFlag(FLAGS_aggregation_threshold);
  parameters.aggregation_timeout = quic::QuicTimeDelta(
      quiche::GetQuicheCommandLineFlag(FLAGS_aggregation_timeout));

  absl::Duration group_duration =
      quiche::GetQuicheCommandLineFlag(FLAGS_group_duration);
  if (group_duration > absl::ZeroDuration()) {
    parameters.keyframe_interval =
        absl::ToDoubleSeconds(group_duration) * parameters.fps;
  }

  std::string raw_delivery_order = absl::AsciiStrToLower(
      quiche::GetQuicheCommandLineFlag(FLAGS_delivery_order));
  if (raw_delivery_order == "asc") {
    parameters.delivery_order = moqt::MoqtDeliveryOrder::kAscending;
  } else if (raw_delivery_order == "desc") {
    parameters.delivery_order = moqt::MoqtDeliveryOrder::kDescending;
  } else {
    std::cerr << "--delivery_order must be 'asc' or 'desc'." << std::endl;
    return 1;
  }

  moqt::test::MoqtSimulator simulator(parameters);
  simulator.Run();

  std::string output_format =
      quiche::GetQuicheCommandLineFlag(FLAGS_output_format);
  if (output_format.empty()) {
    simulator.HumanReadableOutput();
  } else {
    simulator.CustomOutput(output_format);
  }
  return 0;
}
