//! Shared guard against silently clobbering an existing output file.
//!
//! Several commands write a `--output` artifact. Re-running one must not destroy
//! a hand-edited or version-controlled file without a `--force` opt-in, so a
//! `drift capture` cannot quietly overwrite the baseline every later `drift
//! check` reads.

use std::path::Path;

use anyhow::{bail, Result};

/// Error out when `path` already exists and `force` is not set.
///
/// Lets a writer refuse to overwrite an existing artifact unless the caller
/// passed `--force`, so a re-run cannot silently clobber a tracked or
/// hand-edited file.
pub(crate) fn ensure_overwritable(path: &Path, force: bool) -> Result<()> {
    if force {
        return Ok(());
    }
    // Refuse only when there is real content to lose. A 0-byte file is almost
    // always a placeholder (a freshly-created temp file, an empty `touch`), so
    // overwriting it is safe and keeps the common "write to a known path"
    // pattern working without forcing every caller to pass --force.
    if std::fs::metadata(path)
        .map(|m| m.len() > 0)
        .unwrap_or(false)
    {
        bail!(
            "{} already exists; pass --force to overwrite it",
            path.display()
        );
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn refuses_an_existing_file_without_force() {
        let dir = tempfile::tempdir().unwrap();
        let path = dir.path().join("artifact.json");
        std::fs::write(&path, "{}").unwrap();
        assert!(ensure_overwritable(&path, false).is_err());
        assert!(ensure_overwritable(&path, true).is_ok());
    }

    #[test]
    fn allows_a_new_path() {
        let dir = tempfile::tempdir().unwrap();
        let path = dir.path().join("new.json");
        assert!(ensure_overwritable(&path, false).is_ok());
    }

    #[test]
    fn allows_overwriting_an_empty_placeholder() {
        // A 0-byte file (e.g. a freshly-created temp file) carries nothing to
        // lose, so it is overwritable without --force.
        let dir = tempfile::tempdir().unwrap();
        let path = dir.path().join("placeholder.json");
        std::fs::write(&path, "").unwrap();
        assert!(ensure_overwritable(&path, false).is_ok());
    }
}
