// Code generated by ndpgen. DO NOT EDIT.
//
// This file contains export wrappers for the WebSocketCallback capability.
// It is intended for use in Navidrome plugins built with extism-pdk.

use serde::{Deserialize, Serialize};
use base64::Engine as _;
use base64::engine::general_purpose::STANDARD as BASE64;

mod base64_bytes {
    use serde::{self, Deserialize, Deserializer, Serializer};
    use base64::Engine as _;
    use base64::engine::general_purpose::STANDARD as BASE64;

    pub fn serialize<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&BASE64.encode(bytes))
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        BASE64.decode(&s).map_err(serde::de::Error::custom)
    }
}

// Helper functions for skip_serializing_if with numeric types
#[allow(dead_code)]
fn is_zero_i32(value: &i32) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_u32(value: &u32) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_i64(value: &i64) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_u64(value: &u64) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_f32(value: &f32) -> bool { *value == 0.0 }
#[allow(dead_code)]
fn is_zero_f64(value: &f64) -> bool { *value == 0.0 }
/// OnBinaryMessageRequest is the request provided when a binary message is received.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OnBinaryMessageRequest {
    /// ConnectionID is the unique identifier for the WebSocket connection that received the message.
    #[serde(default)]
    pub connection_id: String,
    /// Data is the binary data received from the WebSocket, encoded as base64.
    #[serde(default)]
    #[serde(with = "base64_bytes")]
    pub data: Vec<u8>,
}
/// OnCloseRequest is the request provided when a WebSocket connection is closed.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OnCloseRequest {
    /// ConnectionID is the unique identifier for the WebSocket connection that was closed.
    #[serde(default)]
    pub connection_id: String,
    /// Code is the WebSocket close status code (e.g., 1000 for normal closure,
    /// 1001 for going away, 1006 for abnormal closure).
    #[serde(default)]
    pub code: i32,
    /// Reason is the human-readable reason for the connection closure, if provided.
    #[serde(default)]
    pub reason: String,
}
/// OnErrorRequest is the request provided when an error occurs on a WebSocket connection.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OnErrorRequest {
    /// ConnectionID is the unique identifier for the WebSocket connection where the error occurred.
    #[serde(default)]
    pub connection_id: String,
    /// Error is the error message describing what went wrong.
    #[serde(default)]
    pub error: String,
}
/// OnTextMessageRequest is the request provided when a text message is received.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OnTextMessageRequest {
    /// ConnectionID is the unique identifier for the WebSocket connection that received the message.
    #[serde(default)]
    pub connection_id: String,
    /// Message is the text message content received from the WebSocket.
    #[serde(default)]
    pub message: String,
}

/// Error represents an error from a capability method.
#[derive(Debug)]
pub struct Error {
    pub message: String,
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.message)
    }
}

impl std::error::Error for Error {}

impl Error {
    pub fn new(message: impl Into<String>) -> Self {
        Self { message: message.into() }
    }
}

/// TextMessageProvider provides the OnTextMessage function.
pub trait TextMessageProvider {
    fn on_text_message(&self, req: OnTextMessageRequest) -> Result<(), Error>;
}

/// Register the on_text_message export.
/// This macro generates the WASM export function for this method.
#[macro_export]
macro_rules! register_websocket_text_message {
    ($plugin_type:ty) => {
        #[extism_pdk::plugin_fn]
        pub fn nd_websocket_on_text_message(
            req: extism_pdk::Json<$crate::websocket::OnTextMessageRequest>
        ) -> extism_pdk::FnResult<()> {
            let plugin = <$plugin_type>::default();
            $crate::websocket::TextMessageProvider::on_text_message(&plugin, req.into_inner())?;
            Ok(())
        }
    };
}

/// BinaryMessageProvider provides the OnBinaryMessage function.
pub trait BinaryMessageProvider {
    fn on_binary_message(&self, req: OnBinaryMessageRequest) -> Result<(), Error>;
}

/// Register the on_binary_message export.
/// This macro generates the WASM export function for this method.
#[macro_export]
macro_rules! register_websocket_binary_message {
    ($plugin_type:ty) => {
        #[extism_pdk::plugin_fn]
        pub fn nd_websocket_on_binary_message(
            req: extism_pdk::Json<$crate::websocket::OnBinaryMessageRequest>
        ) -> extism_pdk::FnResult<()> {
            let plugin = <$plugin_type>::default();
            $crate::websocket::BinaryMessageProvider::on_binary_message(&plugin, req.into_inner())?;
            Ok(())
        }
    };
}

/// ErrorProvider provides the OnError function.
pub trait ErrorProvider {
    fn on_error(&self, req: OnErrorRequest) -> Result<(), Error>;
}

/// Register the on_error export.
/// This macro generates the WASM export function for this method.
#[macro_export]
macro_rules! register_websocket_error {
    ($plugin_type:ty) => {
        #[extism_pdk::plugin_fn]
        pub fn nd_websocket_on_error(
            req: extism_pdk::Json<$crate::websocket::OnErrorRequest>
        ) -> extism_pdk::FnResult<()> {
            let plugin = <$plugin_type>::default();
            $crate::websocket::ErrorProvider::on_error(&plugin, req.into_inner())?;
            Ok(())
        }
    };
}

/// CloseProvider provides the OnClose function.
pub trait CloseProvider {
    fn on_close(&self, req: OnCloseRequest) -> Result<(), Error>;
}

/// Register the on_close export.
/// This macro generates the WASM export function for this method.
#[macro_export]
macro_rules! register_websocket_close {
    ($plugin_type:ty) => {
        #[extism_pdk::plugin_fn]
        pub fn nd_websocket_on_close(
            req: extism_pdk::Json<$crate::websocket::OnCloseRequest>
        ) -> extism_pdk::FnResult<()> {
            let plugin = <$plugin_type>::default();
            $crate::websocket::CloseProvider::on_close(&plugin, req.into_inner())?;
            Ok(())
        }
    };
}
