//! WebSocket message codec.
//!
//! This module defines the encoding and decoding logic used by WebSocket
//! sessions to translate between raw WebSocket frames and typed protocol
//! messages.
//!
//! The codec is responsible solely for serialization and deserialization;
//! protocol sequencing and validation are handled elsewhere.

use crate::error::ClientError;
use crate::ws::protocol::{UserWsClientMessage, UserWsServerMessage};

/// WebSocket message codec.
///
/// A codec defines how client and server protocol messages are serialized
/// into WebSocket frames and deserialized back into strongly typed values.
///
/// Implementations must be deterministic and symmetric: any message encoded
/// by the codec must be decodable by the same codec.
pub trait WsCodec: Send + Sync + 'static {
    /// Encode a client protocol message into a WebSocket frame.
    ///
    /// This method is invoked before messages are written to the WebSocket sink.
    ///
    /// # Errors
    /// Returns an error if the message cannot be serialized.
    fn encode_client(&self, msg: &UserWsClientMessage) -> Result<String, ClientError>;

    /// Decode a WebSocket frame into a server protocol message.
    ///
    /// This method is invoked for each incoming WebSocket frame.
    ///
    /// # Errors
    /// Returns an error if the frame is invalid, unsupported, or cannot be
    /// deserialized into a protocol message.
    fn decode_server(&self, text: &str) -> Result<UserWsServerMessage, ClientError>;
}

/// JSON WebSocket codec.
///
/// This codec serializes protocol messages as JSON text frames and expects
/// server messages to be encoded using the same format.
///
/// This is the default codec used by the SDK.
#[derive(Debug, Clone, Copy, Default)]
pub struct JsonWsCodec;

/// JSON-based codec implementation.
///
/// Uses `serde_json` for serialization and deserialization of protocol
/// messages.
impl WsCodec for JsonWsCodec {
    fn encode_client(&self, msg: &UserWsClientMessage) -> Result<String, ClientError> {
        Ok(serde_json::to_string(msg)?)
    }

    fn decode_server(&self, text: &str) -> Result<UserWsServerMessage, ClientError> {
        Ok(serde_json::from_str(text)?)
    }
}
