//! Parser for the `.mix.json` edit list: an array of segments, each with a
//! millisecond `[start_ts, end_ts)` window relative to the recording start.
//!
//! Each segment keeps its full original JSON object (`raw`) so `metadata.json`
//! can echo every field verbatim — including fields cutmerge does not itself
//! interpret — even after adjacent segments are merged into one clip.

use std::path::Path;

use anyhow::{Context, Result};
use serde::Deserialize;
use serde_json::Value;

/// One edit-list segment. `index` / `start_ts` / `end_ts` are parsed out for the
/// cut/merge logic; `raw` is the untouched original entry for the metadata echo.
#[derive(Debug, Clone)]
pub struct Segment {
    pub index: u32,
    /// Start of the clip, milliseconds from the recording start.
    pub start_ts: u64,
    /// End of the clip, milliseconds from the recording start.
    pub end_ts: u64,
    /// The original edit-list entry, verbatim, echoed into `metadata.json`.
    pub raw: Value,
}

/// The fields cutmerge requires from every edit-list entry. Extra fields are
/// ignored here (serde skips unknown keys by default) but preserved in
/// [`Segment::raw`].
#[derive(Deserialize)]
struct SegmentFields {
    index: u32,
    start_ts: u64,
    end_ts: u64,
}

pub fn load(path: &Path) -> Result<Vec<Segment>> {
    let text = std::fs::read_to_string(path)
        .with_context(|| format!("reading edit list {}", path.display()))?;
    let values: Vec<Value> = serde_json::from_str(&text)
        .with_context(|| format!("parsing edit list {}", path.display()))?;

    let mut segments = Vec::with_capacity(values.len());
    for value in values {
        let fields: SegmentFields = serde_json::from_value(value.clone()).with_context(|| {
            format!(
                "edit-list entry missing index/start_ts/end_ts in {}",
                path.display()
            )
        })?;
        segments.push(Segment {
            index: fields.index,
            start_ts: fields.start_ts,
            end_ts: fields.end_ts,
            raw: value,
        });
    }
    Ok(segments)
}
