use std::env;
use std::fs;
use std::path::PathBuf;

use rho_core::{RhoResult, ensure_parent, normalize_actor_id, require_arg, yaml_quote};

fn usage() -> ! {
    eprintln!(
        "usage: rho-result publish --shared-root <path> --request-id <id> --result-id <id> --from <id> --to <id> --artifact <path> [--text <text>]"
    );
    std::process::exit(2);
}

fn main() {
    if let Err(error) = run() {
        eprintln!("{error}");
        std::process::exit(1);
    }
}

fn run() -> RhoResult<()> {
    let args: Vec<String> = env::args().skip(1).collect();
    if args.first().map(String::as_str) != Some("publish") {
        usage();
    }
    let rest = &args[1..];
    let shared_root = PathBuf::from(require_arg(rest, "--shared-root").unwrap_or_else(|_| usage()));
    let request_id = require_arg(rest, "--request-id").unwrap_or_else(|_| usage());
    let result_id = require_arg(rest, "--result-id").unwrap_or_else(|_| usage());
    let from = normalize_actor_id(&require_arg(rest, "--from").unwrap_or_else(|_| usage()))?;
    let to = normalize_actor_id(&require_arg(rest, "--to").unwrap_or_else(|_| usage()))?;
    let artifact = require_arg(rest, "--artifact").unwrap_or_else(|_| usage());
    let text = rho_core::arg_value(rest, "--text")
        .unwrap_or_else(|| format!("Result released for {request_id}."));
    let manifest = shared_root
        .join(".rho/results")
        .join(format!("{request_id}.yaml"));
    ensure_parent(&manifest)?;
    fs::write(
        &manifest,
        format!(
            "version: 1\nresult:\n  id: {}\n  request_id: {}\n  from: {}\n  to: {}\n  status: \"released\"\n  artifact_paths:\n    - {}\n",
            yaml_quote(&result_id),
            yaml_quote(&request_id),
            yaml_quote(&from),
            yaml_quote(&to),
            yaml_quote(&artifact),
        ),
    )?;

    let inbox = shared_root
        .join(".rho/inbox")
        .join(&to)
        .join(format!("result-{request_id}.yaml"));
    ensure_parent(&inbox)?;
    fs::write(
        &inbox,
        format!(
            "version: 1\nmessage:\n  id: {}\n  from: {}\n  to: {}\n  type: \"result_available\"\n  related_request_id: {}\n  body:\n    text: {}\n    result_manifest: {}\n",
            yaml_quote(&format!("result-{request_id}")),
            yaml_quote(&from),
            yaml_quote(&to),
            yaml_quote(&request_id),
            yaml_quote(&text),
            yaml_quote(&manifest.display().to_string()),
        ),
    )?;
    println!("{}", manifest.display());
    Ok(())
}
