//! Implements `limb unlock`. Reverses `limb lock`.

use anyhow::Result;

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

/// Runs `limb unlock`.
///
/// Thin wrapper over `git worktree unlock`.
///
/// # Errors
///
/// Returns an error if the name does not match or the git invocation
/// fails (e.g. the worktree is not locked).
pub fn run(ctx: &Context, args: &UnlockArgs) -> 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(),
                "dry_run": true,
            });
            println!("{}", serde_json::to_string_pretty(&out)?);
        } else if !ctx.quiet {
            eprintln!("would unlock: {}", args.name);
        }
        return Ok(());
    }

    let path_str = target.path.to_string_lossy().into_owned();
    git::run(&repo, &["worktree", "unlock", &path_str])?;

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