use async_trait::async_trait;
use chainfire_types::node::NodeInfo;
use crate::error::Result;
use std::net::SocketAddr;

/// Abstract interface for Gossip protocol
#[async_trait]
pub trait Gossip: Send + Sync {
    /// Start the gossip agent
    async fn start(&self) -> Result<()>;
    
    /// Join a cluster via seed nodes
    async fn join(&self, seeds: &[SocketAddr]) -> Result<()>;
    
    /// Announce presence to a specific node
    async fn announce(&self, addr: SocketAddr) -> Result<()>;
    
    /// Get list of known members
    fn members(&self) -> Vec<NodeInfo>;
    
    /// Shutdown the gossip agent
    async fn shutdown(&self) -> Result<()>;
}

/// Abstract interface for Consensus protocol (Raft)
#[async_trait]
pub trait Consensus: Send + Sync {
    /// Initialize the consensus module
    async fn initialize(&self) -> Result<()>;
    
    /// Start the event loop
    async fn run(&self) -> Result<()>;
    
    /// Propose a command to the state machine
    async fn propose(&self, data: Vec<u8>) -> Result<u64>;
    
    /// Add a node to the consensus group
    async fn add_node(&self, node_id: u64, addr: String, as_learner: bool) -> Result<()>;
    
    /// Remove a node from the consensus group
    async fn remove_node(&self, node_id: u64) -> Result<()>;
    
    /// Check if this node is the leader
    fn is_leader(&self) -> bool;
    
    /// Get the current leader ID
    fn leader_id(&self) -> Option<u64>;
}

/// Abstract interface for State Machine
pub trait StateMachine: Send + Sync {
    /// Apply a committed entry
    fn apply(&self, index: u64, data: &[u8]) -> Result<Vec<u8>>;
    
    /// Take a snapshot of current state
    fn snapshot(&self) -> Result<Vec<u8>>;
    
    /// Restore state from a snapshot
    fn restore(&self, snapshot: &[u8]) -> Result<()>;
}