//! Internal state management for ServiceDiscovery.

use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use tokio::sync::{broadcast, watch};

use crate::event::ClusterEvent;
use crate::types::Node;

/// Default capacity for the event broadcast channel.
pub(super) const DEFAULT_EVENT_CHANNEL_CAPACITY: usize = 256;

/// Internal state for ServiceDiscovery.
///
/// This struct is wrapped in an `Arc` to allow cheap cloning of `ServiceDiscovery`.
pub(super) struct ServiceDiscoveryInner {
    pub etcd_endpoints: Vec<String>,
    pub group_name: String,

    /// Event broadcast channel for ClusterEvent subscribers
    pub event_tx: broadcast::Sender<ClusterEvent>,

    /// Watch channel for nodes state
    pub nodes_tx: watch::Sender<Arc<Vec<Node>>>,
    pub nodes_rx: watch::Receiver<Arc<Vec<Node>>>,

    /// Watch channel for leader state
    pub leader_tx: watch::Sender<Option<Node>>,
    pub leader_rx: watch::Receiver<Option<Node>>,

    /// Watch channel for ready state
    pub ready_tx: watch::Sender<bool>,
    pub ready_rx: watch::Receiver<bool>,

    /// Track if this is the first connection
    pub first_connect: AtomicBool,
}

impl ServiceDiscoveryInner {
    /// Creates a new ServiceDiscoveryInner with initialized channels.
    pub fn new(etcd_endpoints: Vec<String>, group_name: String) -> Self {
        let (event_tx, _) = broadcast::channel(DEFAULT_EVENT_CHANNEL_CAPACITY);
        let (nodes_tx, nodes_rx) = watch::channel(Arc::new(Vec::new()));
        let (leader_tx, leader_rx) = watch::channel(None);
        let (ready_tx, ready_rx) = watch::channel(false);

        ServiceDiscoveryInner {
            etcd_endpoints,
            group_name,
            event_tx,
            nodes_tx,
            nodes_rx,
            leader_tx,
            leader_rx,
            ready_tx,
            ready_rx,
            first_connect: AtomicBool::new(true),
        }
    }
}
