#[cfg(not(coverage))]
/// Keeps `write_report_dir` explicit because it sits on CLI orchestration, where operators need deterministic exits and artifact paths.
/// Inputs are the typed parameters; output is the return value or side effect.
fn write_report_dir(
    report_dir: &std::path::Path,
    human_report: &str,
    output: &SyncAnalyzeOutput<'_>,
) -> Result<()> {
    std::fs::create_dir_all(report_dir)
        .with_context(|| format!("creating report directory {}", report_dir.display()))?;
    std::fs::write(report_dir.join("report.txt"), human_report)
        .with_context(|| format!("writing {}", report_dir.join("report.txt").display()))?;
    std::fs::write(
        report_dir.join("report.json"),
        serde_json::to_string_pretty(output).context("serializing JSON report")?,
    )
    .with_context(|| format!("writing {}", report_dir.join("report.json").display()))?;
    write_events_csv(&report_dir.join("events.csv"), output.report)?;
    Ok(())
}

#[cfg(not(coverage))]
/// Keeps `write_events_csv` explicit because it sits on CLI orchestration, where operators need deterministic exits and artifact paths.
/// Inputs are the typed parameters; output is the return value or side effect.
fn write_events_csv(path: &std::path::Path, report: &SyncAnalysisReport) -> Result<()> {
    let mut csv = String::from(
        "event_id,server_event_id,event_code,video_time_s,audio_time_s,skew_ms,confidence\n",
    );
    for event in &report.paired_events {
        csv.push_str(&format!(
            "{},{},{},{:.9},{:.9},{:.6},{:.6}\n",
            event.event_id,
            optional_usize(event.server_event_id),
            optional_u32(event.event_code),
            event.video_time_s,
            event.audio_time_s,
            event.skew_ms,
            event.confidence
        ));
    }
    std::fs::write(path, csv).with_context(|| format!("writing {}", path.display()))
}

#[cfg(not(coverage))]
fn optional_usize(value: Option<usize>) -> String {
    value.map(|value| value.to_string()).unwrap_or_default()
}

#[cfg(not(coverage))]
fn optional_u32(value: Option<u32>) -> String {
    value.map(|value| value.to_string()).unwrap_or_default()
}
