//! Implements `limb lock`. Locks a worktree against prune and remove.

use anyhow::Result;

use crate::cli::LockArgs;
use crate::context::Context;
use crate::{git, worktree};

/// Runs `limb lock`.
///
/// Locks the named worktree via `git worktree lock`, optionally recording
/// the `--reason` (shown in `git worktree list`).
///
/// # Errors
///
/// Returns an error if the name does not match or the git invocation
/// fails (e.g. the worktree is already locked).
pub fn run(ctx: &Context, args: &LockArgs) -> Result<()> {
    let repo = ctx.repo()?;
    let target = worktree::require(&repo, &args.name)?;

    if args.dry_run {
        if ctx.json {
            let out = serde_json::json!({
                "name": args.name,
                "path": target.path.display().to_string(),
                "reason": args.reason,
                "dry_run": true,
            });
            println!("{}", serde_json::to_string_pretty(&out)?);
        } else if !ctx.quiet {
            eprintln!("would lock: {}", args.name);
        }
        return Ok(());
    }

    let path_str = target.path.to_string_lossy().into_owned();
    let mut cmd_args: Vec<&str> = vec!["worktree", "lock"];
    if let Some(reason) = args.reason.as_deref() {
        cmd_args.push("--reason");
        cmd_args.push(reason);
    }
    cmd_args.push(&path_str);
    git::run(&repo, &cmd_args)?;

    if ctx.json {
        let out = serde_json::json!({
            "name": args.name,
            "path": target.path.display().to_string(),
            "reason": args.reason,
        });
        println!("{}", serde_json::to_string_pretty(&out)?);
    } else if !ctx.quiet {
        let ok = crate::style::OK;
        anstream::eprintln!("{ok}✓{ok:#} locked: {}", args.name);
    }
    Ok(())
}
