#[cfg(coverage)]
/// Read the upstream stale-drop budget used by coverage-only relay loops.
///
/// Inputs: optional `LESAVKA_UPSTREAM_STALE_DROP_MS` environment override.
/// Output: a bounded duration used to decide whether synthetic packets remain
/// fresh enough to play. The helper exists so tests exercise the same
/// freshness-first policy that protects real calls from backlog growth.
fn upstream_stale_drop_budget() -> Duration {
    let drop_ms = std::env::var("LESAVKA_UPSTREAM_STALE_DROP_MS")
        .ok()
        .and_then(|value| value.trim().parse::<u64>().ok())
        .unwrap_or(80);
    Duration::from_millis(drop_ms)
}

#[cfg(coverage)]
/// Keeps `retain_freshest_video_packet` explicit because it sits on relay RPC orchestration, where hardware failures must surface without stopping the server.
/// Inputs are the typed parameters; output is the return value or side effect.
fn retain_freshest_video_packet(
    pending: &mut std::collections::VecDeque<VideoPacket>,
) -> usize {
    if pending.len() <= 1 {
        return 0;
    }
    let newest = pending.pop_back().expect("non-empty pending video queue");
    let dropped = pending.len();
    pending.clear();
    pending.push_back(newest);
    dropped
}

#[cfg(coverage)]
const AUDIO_PENDING_LIVE_WINDOW_PACKETS: usize = 8;

#[cfg(coverage)]
/// Keeps `retain_freshest_audio_packet` explicit because it sits on relay RPC orchestration, where hardware failures must surface without stopping the server.
/// Inputs are the typed parameters; output is the return value or side effect.
fn retain_freshest_audio_packet(
    pending: &mut std::collections::VecDeque<AudioPacket>,
) -> usize {
    if pending.len() <= AUDIO_PENDING_LIVE_WINDOW_PACKETS {
        return 0;
    }
    let dropped = pending.len() - AUDIO_PENDING_LIVE_WINDOW_PACKETS;
    pending.drain(..dropped);
    dropped
}

#[cfg(coverage)]
/// Return a playable upstream plan while collapsing all wait/drop decisions.
///
/// Inputs: planner decision from `UpstreamMediaRuntime`. Output: `Some(plan)`
/// only when playback should proceed. This keeps coverage tests focused on
/// the relay branch contract rather than duplicating planner internals.
fn coverage_playable_plan(
    decision: lesavka_server::upstream_media_runtime::UpstreamPlanDecision,
) -> Option<lesavka_server::upstream_media_runtime::PlannedUpstreamPacket> {
    match decision {
        lesavka_server::upstream_media_runtime::UpstreamPlanDecision::Play(plan) => Some(plan),
        lesavka_server::upstream_media_runtime::UpstreamPlanDecision::AwaitingPair
        | lesavka_server::upstream_media_runtime::UpstreamPlanDecision::DropBeforeOverlap
        | lesavka_server::upstream_media_runtime::UpstreamPlanDecision::DropStale(_)
        | lesavka_server::upstream_media_runtime::UpstreamPlanDecision::StartupFailed(_) => None,
    }
}

#[cfg(coverage)]
/// Requeue audio when the planner needs more paired media before playback.
///
/// Inputs: pending audio queue, packet, and inbound stream state. Output:
/// whether the packet was requeued. This mirrors the live relay behavior where
/// audio may need to wait for video overlap but must not resurrect closed input.
fn coverage_requeue_audio_packet(
    pending: &mut std::collections::VecDeque<AudioPacket>,
    pkt: AudioPacket,
    inbound_closed: bool,
) -> bool {
    if inbound_closed {
        return false;
    }
    pending.push_front(pkt);
    true
}

#[cfg(coverage)]
/// Requeue video when the planner needs more paired media before playback.
///
/// Inputs: pending video queue, packet, and inbound stream state. Output:
/// whether the packet was requeued. This keeps the video path freshness-first
/// while still allowing a short wait for the audio timing master.
fn coverage_requeue_video_packet(
    pending: &mut std::collections::VecDeque<VideoPacket>,
    pkt: VideoPacket,
    inbound_closed: bool,
) -> bool {
    if inbound_closed {
        return false;
    }
    pending.push_front(pkt);
    true
}

#[cfg(coverage)]
/// Record a coverage-only video freeze when audio never becomes the timing master.
///
/// Inputs: upstream media runtime being observed. Output: runtime telemetry
/// side effect. This documents the otherwise silent branch where video is
/// intentionally dropped instead of playing out of sync.
fn coverage_record_video_wait_failure(
    upstream_media_rt: &lesavka_server::upstream_media_runtime::UpstreamMediaRuntime,
) {
    upstream_media_rt.record_video_freeze("coverage video froze awaiting audio master");
}

#[cfg(coverage)]
/// Drop stale queued video down to the newest packet.
///
/// Inputs: pending video queue. Output: number of dropped packets. The relay
/// uses this freshness-first escape hatch so a stalled client cannot create a
/// growing RCT video delay.
fn coverage_drop_late_video_packet(
    pending: &mut std::collections::VecDeque<VideoPacket>,
) -> usize {
    retain_freshest_video_packet(pending)
}

#[cfg(coverage)]
/// Convert an audio planner decision into a playable plan or queue mutation.
///
/// Inputs: planner decision, pending queue, current packet, inbound state, and
/// stale budget. Output: playable plan when fresh enough. This keeps the audio
/// test harness faithful to the live decision order without duplicating a full
/// streaming RPC in every branch test.
fn coverage_audio_plan_from_decision(
    decision: lesavka_server::upstream_media_runtime::UpstreamPlanDecision,
    pending: &mut std::collections::VecDeque<AudioPacket>,
    pkt: AudioPacket,
    inbound_closed: bool,
    stale_drop_budget: Duration,
) -> Option<lesavka_server::upstream_media_runtime::PlannedUpstreamPacket> {
    let Some(plan) = coverage_playable_plan(decision) else {
        coverage_requeue_audio_packet(pending, pkt, inbound_closed);
        return None;
    };
    if plan.late_by > stale_drop_budget {
        return None;
    }
    Some(plan)
}

#[cfg(coverage)]
/// Convert a video planner decision into a playable plan or freshness drop.
///
/// Inputs: planner decision, pending queue, current packet, inbound state, and
/// stale budget. Output: playable plan when fresh enough. This protects the
/// branch where video must sacrifice smoothness rather than accumulate delay.
fn coverage_video_plan_from_decision(
    decision: lesavka_server::upstream_media_runtime::UpstreamPlanDecision,
    pending: &mut std::collections::VecDeque<VideoPacket>,
    pkt: VideoPacket,
    inbound_closed: bool,
    stale_drop_budget: Duration,
) -> Option<lesavka_server::upstream_media_runtime::PlannedUpstreamPacket> {
    let Some(plan) = coverage_playable_plan(decision) else {
        coverage_requeue_video_packet(pending, pkt, inbound_closed);
        return None;
    };
    if plan.late_by > stale_drop_budget {
        let _ = coverage_drop_late_video_packet(pending);
        return None;
    }
    Some(plan)
}

#[cfg(coverage)]
/// Check whether the audio master is ready before video can be presented.
///
/// Inputs: upstream runtime and readiness result from the waiter. Output: true
/// when video may play. A false result records telemetry because this branch is
/// a real call-quality signal, not just a skipped packet.
fn coverage_audio_master_ready(
    upstream_media_rt: &lesavka_server::upstream_media_runtime::UpstreamMediaRuntime,
    ready: bool,
) -> bool {
    if ready {
        return true;
    }
    coverage_record_video_wait_failure(upstream_media_rt);
    false
}
