// r8r: rust port of n8n.io
// Initial author: Michael Cochran <mcochran@cochranblock.org>
// Built for: Tanner Woodrum, intended cofounder
// License: Unlicense (public domain dedication, see UNLICENSE)
//
// `stop_and_error` — explicit halt. Returns NodeError::Other with a
// configurable message. Useful for guard-rails (e.g., If → StopAndError).

use async_trait::async_trait;
use crate::core::error::NodeError;
use crate::core::types::*;
use crate::engine::{ExecuteCtx, Node, NodeFactory};
use std::sync::Arc;

pub struct StopAndErrorNode;

static META: NodeMetadata = NodeMetadata {
    name: "stop_and_error",
    display_name: "Stop And Error",
    version: &[1],
    group: &["transform"],
    description: "Halt the workflow with a custom error message",
    inputs: 1,
    outputs: 0,
    properties: &[],
    credentials: &[],
};

#[async_trait]
impl Node for StopAndErrorNode {
    fn metadata(&self) -> &'static NodeMetadata { &META }

    async fn execute(&self, ctx: &mut ExecuteCtx<'_>) -> Result<NodeOutput, NodeError> {
        let msg = ctx.param_opt_str("message")
            .unwrap_or_else(|| "stopped by stop_and_error node".to_string());
        Err(NodeError::Other(msg))
    }
}

inventory::submit! { NodeFactory::new("stop_and_error", || Arc::new(StopAndErrorNode)) }
