/*
 *  Copyright (c) 2025 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 "video/timing/simulator/rtc_event_log_driver.h"

#include <cstdint>
#include <memory>
#include <optional>
#include <set>
#include <utility>

#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/environment/environment_factory.h"
#include "api/environment/force_test_environment.h"
#include "api/field_trials.h"
#include "api/sequence_checker.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
#include "logging/rtc_event_log/rtc_event_log_parser.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "test/time_controller/simulated_time_task_queue_controller.h"
#include "video/timing/simulator/rtp_packet_simulator.h"
#include "video/timing/simulator/rtt_simulator.h"

namespace webrtc::video_timing_simulator {
namespace {
// Creates FieldTrials that are acceptable both in unittests and in production.
// Note: This will not capture the command line --force_fieldtrials flag,
// as it bypasses the test environment check without merging the flag.
std::unique_ptr<FieldTrials> CreateFieldTrials(absl::string_view s) {
  AutoBypassTestEnvironmentCheck bypass;
  return std::make_unique<FieldTrials>(s, /*is_test=*/true);
}
}  // namespace

RtcEventLogDriver::RtcEventLogDriver(
    const Config& config,
    const ParsedRtcEventLog* absl_nonnull parsed_log,
    absl::string_view field_trials_string,
    RtcEventLogDriver::StreamInterfaceFactory stream_factory)
    : config_(config),
      time_controller_(Timestamp::Zero()),
      env_(CreateEnvironment(CreateFieldTrials(field_trials_string),
                             time_controller_.GetClock(),
                             time_controller_.GetTaskQueueFactory())),
      parsed_log_(*parsed_log),
      stream_factory_(std::move(stream_factory)),
      prev_log_timestamp_(std::nullopt),
      simulator_queue_(time_controller_.GetTaskQueueFactory()->CreateTaskQueue(
          "simulator_queue",
          TaskQueueFactory::Priority::kNormal)),
      packet_simulator_(env_),
      rtt_callback_adapter_(this) {
  RTC_DCHECK(stream_factory_) << "stream_factory must be provided";

  bool done = false;
  simulator_queue_->PostTask([this, &done]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    rtt_simulator_ = std::make_unique<RttSimulator>(
        env_, simulator_queue_.get(), &rtt_callback_adapter_);
    done = true;
  });
  time_controller_.AdvanceTime(TimeDelta::Zero());
  RTC_DCHECK(done);

  // Config events.
  processor_.AddEvents(
      parsed_log_.video_recv_configs(),
      [this](const auto& config) { OnLoggedVideoRecvConfig(config); });

  // RTP video packet events (media + RTX).
  for (const auto& stream : parsed_log_.incoming_rtp_packets_by_ssrc()) {
    bool is_video = parsed_log_.GetMediaType(
                        stream.ssrc, PacketDirection::kIncomingPacket) ==
                    ParsedRtcEventLog::MediaType::VIDEO;
    if (!is_video) {
      continue;
    }
    processor_.AddEvents(stream.incoming_packets, [this](const auto& packet) {
      OnLoggedRtpPacketIncoming(packet);
    });
  }

  // RTCP packet events (outgoing).
  processor_.AddEvents(
      parsed_log_.sender_reports(PacketDirection::kOutgoingPacket),
      [this](const auto& packet) {
        OnLoggedRtcpPacketSenderReportOutgoing(packet);
      },
      PacketDirection::kOutgoingPacket);
  processor_.AddEvents(
      parsed_log_.extended_reports(PacketDirection::kOutgoingPacket),
      [this](const auto& packet) {
        OnLoggedRtcpPacketExtendedReportsOutgoing(packet);
      },
      PacketDirection::kOutgoingPacket);

  // RTCP packet events (incoming).
  processor_.AddEvents(
      parsed_log_.sender_reports(PacketDirection::kIncomingPacket),
      [this](const auto& packet) {
        OnLoggedRtcpPacketSenderReportIncoming(packet);
      },
      PacketDirection::kIncomingPacket);
  processor_.AddEvents(
      parsed_log_.receiver_reports(PacketDirection::kIncomingPacket),
      [this](const auto& packet) {
        OnLoggedRtcpPacketReceiverReportIncoming(packet);
      },
      PacketDirection::kIncomingPacket);
  processor_.AddEvents(
      parsed_log_.extended_reports(PacketDirection::kIncomingPacket),
      [this](const auto& packet) {
        OnLoggedRtcpPacketExtendedReportsIncoming(packet);
      },
      PacketDirection::kIncomingPacket);
}

RtcEventLogDriver::~RtcEventLogDriver() = default;

void RtcEventLogDriver::Simulate() {
  // Walk through events in timestamp order and call the registered handlers.
  processor_.ProcessEventsInOrder();

  // Attempt to get straggling frames out by advancing time a little bit after
  // the last logged event.
  time_controller_.AdvanceTime(kShutdownAdvanceTimeSlack);

  // Tear down on the queue.
  bool done = false;
  simulator_queue_->PostTask([this, &done]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    TeardownOnQueue();
    done = true;
  });
  time_controller_.AdvanceTime(TimeDelta::Zero());
  RTC_DCHECK(done);
}

void RtcEventLogDriver::AdvanceTime(Timestamp log_timestamp) {
  if (!prev_log_timestamp_) {
    // For the first event, set the clock in absolute terms.
    prev_log_timestamp_ = log_timestamp;
    time_controller_.AdvanceTime(log_timestamp - env_.clock().CurrentTime());
    RTC_DCHECK_EQ(env_.clock().CurrentTime(), log_timestamp);
    return;
  }
  TimeDelta duration = log_timestamp - *prev_log_timestamp_;
  prev_log_timestamp_ = log_timestamp;
  if (duration < TimeDelta::Zero()) {
    RTC_LOG(LS_ERROR)
        << "Non-monotonic sequence of timestamps. Will not advance time."
        << " (simulated_ts=" << env_.clock().CurrentTime() << ")";
    return;
  }
  time_controller_.AdvanceTime(duration);
}

void RtcEventLogDriver::HandleEvent(Timestamp log_timestamp,
                                    absl::AnyInvocable<void() &&> handler) {
  // Execute all tasks scheduled before the new logged event.
  AdvanceTime(log_timestamp);

  bool done = false;
  simulator_queue_->PostTask([handler = std::move(handler), &done]() mutable {
    std::move(handler)();
    done = true;
  });

  // Execute the logged event itself.
  AdvanceTime(log_timestamp);
  RTC_DCHECK(done) << "Handler was not executed";
}

void RtcEventLogDriver::OnLoggedVideoRecvConfig(
    const webrtc::LoggedVideoRecvConfig& config) {
  uint32_t ssrc = config.config.remote_ssrc;
  uint32_t rtx_ssrc = config.config.rtx_ssrc;
  HandleEvent(config.log_time(), [this, ssrc, rtx_ssrc]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());

    all_known_ssrcs_.insert(ssrc);
    all_known_ssrcs_.insert(rtx_ssrc);

    // Skip setting up stream if not included in the filter.
    if (!config_.ssrc_filter.empty() && !config_.ssrc_filter.contains(ssrc)) {
      RTC_LOG(LS_INFO) << "OnLoggedVideoRecvConfig being skipped for "
                       << "ssrc=" << ssrc << ", rtx_ssrc=" << rtx_ssrc
                       << " (simulated_ts=" << env_.clock().CurrentTime()
                       << ")";
      return;
    }

    RTC_LOG(LS_INFO) << "OnLoggedVideoRecvConfig for "
                     << "ssrc=" << ssrc << ", rtx_ssrc=" << rtx_ssrc
                     << " (simulated_ts=" << env_.clock().CurrentTime() << ")";
    if (auto it = streams_.find(ssrc); it != streams_.end()) {
      if (config_.reuse_streams) {
        // TODO(b/384950328): Support changing RTX SSRCs on the fly?
        RTC_LOG(LS_WARNING)
            << "Stream for ssrc=" << ssrc << " already existed. Reusing it."
            << " (simulated_ts=" << env_.clock().CurrentTime() << ")";
        return;
      } else {
        RTC_LOG(LS_WARNING)
            << "Stream for ssrc=" << ssrc << " already existed. Overwriting it."
            << " (simulated_ts=" << env_.clock().CurrentTime() << ")";
        it->second->Close();
      }
    }
    std::unique_ptr<StreamInterface> stream =
        stream_factory_(env_, ssrc, rtx_ssrc);
    RTC_DCHECK(stream);
    // Keep track of the stream object for ownership purposes.
    streams_[ssrc] = std::move(stream);
    // Also map it by the two SSRCs, for packet demuxing purposes.
    receiving_streams_[ssrc] = streams_[ssrc].get();
    if (rtx_ssrc != 0) {
      receiving_streams_[rtx_ssrc] = streams_[ssrc].get();
    }
  });
}

void RtcEventLogDriver::OnLoggedRtpPacketIncoming(
    const webrtc::LoggedRtpPacketIncoming& packet) {
  HandleEvent(packet.log_time(), [this, &packet]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    uint32_t ssrc = packet.rtp.header.ssrc;
    if (auto it = receiving_streams_.find(ssrc);
        it != receiving_streams_.end()) {
      RtpPacketSimulator::SimulatedPacket simulated_packet =
          packet_simulator_.SimulateRtpPacketReceived(packet.rtp);
      RTC_DCHECK_EQ(simulated_packet.rtp_packet.arrival_time(),
                    packet.log_time());
      RTC_DCHECK_EQ(env_.clock().CurrentTime(), packet.log_time());
      it->second->InsertSimulatedPacket(simulated_packet);
    } else if (!all_known_ssrcs_.contains(ssrc)) {
      RTC_LOG(LS_WARNING) << "Received packet for unknown ssrc=" << ssrc
                          << " (simulated_ts=" << env_.clock().CurrentTime()
                          << ")";
    }
  });
}

void RtcEventLogDriver::OnLoggedRtcpPacketSenderReportOutgoing(
    const LoggedRtcpPacketSenderReport& packet) {
  HandleEvent(packet.log_time(), [this, &packet]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    rtt_simulator_->OnOutgoingSenderReport(packet);
  });
}

void RtcEventLogDriver::OnLoggedRtcpPacketExtendedReportsOutgoing(
    const LoggedRtcpPacketExtendedReports& packet) {
  HandleEvent(packet.log_time(), [this, &packet]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    rtt_simulator_->OnOutgoingExtendedReports(packet);
  });
}

void RtcEventLogDriver::OnLoggedRtcpPacketSenderReportIncoming(
    const LoggedRtcpPacketSenderReport& packet) {
  HandleEvent(packet.log_time(), [this, &packet]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    rtt_simulator_->OnIncomingSenderReport(packet);
  });
}

void RtcEventLogDriver::OnLoggedRtcpPacketReceiverReportIncoming(
    const LoggedRtcpPacketReceiverReport& packet) {
  HandleEvent(packet.log_time(), [this, &packet]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    rtt_simulator_->OnIncomingReceiverReport(packet);
  });
}

void RtcEventLogDriver::OnLoggedRtcpPacketExtendedReportsIncoming(
    const LoggedRtcpPacketExtendedReports& packet) {
  HandleEvent(packet.log_time(), [this, &packet]() {
    RTC_DCHECK_RUN_ON(simulator_queue_.get());
    rtt_simulator_->OnIncomingExtendedReports(packet);
  });
}

void RtcEventLogDriver::UpdateMaxRtt(TimeDelta max_rtt) {
  RTC_DCHECK_RUN_ON(simulator_queue_.get());
  for (auto& stream : streams_) {
    stream.second->UpdateMaxRtt(max_rtt);
  }
}

void RtcEventLogDriver::TeardownOnQueue() {
  RTC_DCHECK_RUN_ON(simulator_queue_.get());
  for (auto& stream : streams_) {
    stream.second->Close();
  }
  all_known_ssrcs_.clear();
  receiving_streams_.clear();
  streams_.clear();
  rtt_simulator_.reset();
}

}  // namespace webrtc::video_timing_simulator
