use crate::documents::{
    OVERLAY_IMPORT_DOCUMENT_FORMAT_VERSION, RuntimeOverlayImportDocument, RuntimeSaveSliceDocument,
    RuntimeStateInputDocument, SAVE_SLICE_DOCUMENT_FORMAT_VERSION,
    STATE_INPUT_DOCUMENT_FORMAT_VERSION,
};

pub fn validate_runtime_state_input_document(
    document: &RuntimeStateInputDocument,
) -> Result<(), String> {
    if document.format_version != STATE_INPUT_DOCUMENT_FORMAT_VERSION {
        return Err(format!(
            "unsupported runtime state input document format_version {} (expected {})",
            document.format_version, STATE_INPUT_DOCUMENT_FORMAT_VERSION
        ));
    }
    if document.input_id.trim().is_empty() {
        return Err("input_id must not be empty".to_string());
    }
    document.state.validate()
}

pub fn validate_runtime_save_slice_document(
    document: &RuntimeSaveSliceDocument,
) -> Result<(), String> {
    if document.format_version != SAVE_SLICE_DOCUMENT_FORMAT_VERSION {
        return Err(format!(
            "unsupported save slice document format_version {} (expected {})",
            document.format_version, SAVE_SLICE_DOCUMENT_FORMAT_VERSION
        ));
    }
    if document.save_slice_id.trim().is_empty() {
        return Err("save_slice_id must not be empty".to_string());
    }
    if document
        .source
        .description
        .as_deref()
        .is_some_and(|text| text.trim().is_empty())
    {
        return Err("save slice source.description must not be empty".to_string());
    }
    if document
        .source
        .original_save_filename
        .as_deref()
        .is_some_and(|text| text.trim().is_empty())
    {
        return Err("save slice source.original_save_filename must not be empty".to_string());
    }
    if document
        .source
        .original_save_sha256
        .as_deref()
        .is_some_and(|text| text.trim().is_empty())
    {
        return Err("save slice source.original_save_sha256 must not be empty".to_string());
    }
    for (index, note) in document.source.notes.iter().enumerate() {
        if note.trim().is_empty() {
            return Err(format!(
                "save slice source.notes[{index}] must not be empty"
            ));
        }
    }
    if document.save_slice.mechanism_family.trim().is_empty() {
        return Err("save_slice.mechanism_family must not be empty".to_string());
    }
    if document.save_slice.mechanism_confidence.trim().is_empty() {
        return Err("save_slice.mechanism_confidence must not be empty".to_string());
    }
    Ok(())
}

pub fn validate_runtime_overlay_import_document(
    document: &RuntimeOverlayImportDocument,
) -> Result<(), String> {
    if document.format_version != OVERLAY_IMPORT_DOCUMENT_FORMAT_VERSION {
        return Err(format!(
            "unsupported overlay import document format_version {} (expected {})",
            document.format_version, OVERLAY_IMPORT_DOCUMENT_FORMAT_VERSION
        ));
    }
    if document.import_id.trim().is_empty() {
        return Err("import_id must not be empty".to_string());
    }
    if document
        .source
        .description
        .as_deref()
        .is_some_and(|text| text.trim().is_empty())
    {
        return Err("overlay import source.description must not be empty".to_string());
    }
    for (index, note) in document.source.notes.iter().enumerate() {
        if note.trim().is_empty() {
            return Err(format!(
                "overlay import source.notes[{index}] must not be empty"
            ));
        }
    }
    if document.base_snapshot_path.trim().is_empty() {
        return Err("base_snapshot_path must not be empty".to_string());
    }
    if document.save_slice_path.trim().is_empty() {
        return Err("save_slice_path must not be empty".to_string());
    }
    Ok(())
}
