//! Event emission functions.

use crate::runtime::{client, Result};
use serde::Serialize;

/// Emit a debug message.
pub async fn emit_debug<T: Serialize>(guid: &str, name: &str, message: &T) -> Result<()> {
    let value = serde_json::to_value(message)?;
    client::debug(guid, name, &value).await
}

/// Emit output from a node.
pub async fn emit_output(guid: &str, output: &[u8], port: i32) -> Result<()> {
    client::emit_output(guid, output, port).await
}

/// Emit input to a node.
pub async fn emit_input(guid: &str, input: &[u8]) -> Result<()> {
    client::emit_input(guid, input).await
}

/// Emit an error.
pub async fn emit_error(guid: &str, name: &str, message: &str) -> Result<()> {
    client::emit_error(guid, name, message).await
}

/// Emit a flow event.
pub async fn emit_flow_event(guid: &str, name: &str) -> Result<()> {
    client::emit_flow_event(guid, name).await
}

/// Make an app request with timeout.
pub async fn app_request(request: &[u8], timeout: i32) -> Result<Vec<u8>> {
    client::app_request(request, timeout).await
}

/// Make an app request V2.
pub async fn app_request_v2(request: &[u8]) -> Result<Vec<u8>> {
    client::app_request_v2(request).await
}

/// Publish to an app.
pub async fn app_publish(request: &[u8]) -> Result<()> {
    client::app_publish(request).await
}

/// Download a file from the app.
pub async fn app_download(id: &str, dir: &str, file: &str) -> Result<String> {
    client::app_download(id, dir, file).await
}

/// Upload a file to the app.
pub async fn app_upload(id: &str, path: &str) -> Result<String> {
    client::app_upload(id, path).await
}

/// Make a gateway request.
pub async fn gateway_request(
    method: &str,
    endpoint: &str,
    body: &str,
    headers: std::collections::HashMap<String, String>,
) -> Result<client::GatewayResponse> {
    client::gateway_request(method, endpoint, body, headers).await
}

/// Make a proxy request.
pub async fn proxy_request(req: client::HttpRequest) -> Result<client::HttpResponse> {
    client::proxy_request(req).await
}

/// Check if the flow is running.
pub async fn is_running() -> Result<bool> {
    client::is_running().await
}

/// Get port connections.
pub async fn get_port_connections(guid: &str, port: i32) -> Result<Vec<crate::runtime::NodeInfo>> {
    client::get_port_connections(guid, port).await
}

/// Get instance access info.
pub async fn get_instance_access() -> Result<client::InstanceAccess> {
    client::get_instance_access().await
}
