#![cfg_attr(test, allow(clippy::panic))]
// meerkat-comms
//! Inter-agent communication for Meerkat instances.

// On wasm32, use tokio_with_wasm as a drop-in replacement for tokio.
#[cfg(target_arch = "wasm32")]
pub mod tokio {
    pub use tokio_with_wasm::alias::*;
}

pub mod identity;
pub mod inbox;
pub mod inproc;
pub mod peer_meta;
pub mod transport;
pub mod trust;
pub mod types;

// Network I/O modules — not available on wasm32
#[cfg(not(target_arch = "wasm32"))]
pub mod io_task;
#[cfg(not(target_arch = "wasm32"))]
pub mod plain_listener;

pub mod agent;
pub(crate) mod classify;
pub mod event_injector;
pub mod mcp;
pub(crate) mod peer_directory_reachability_authority;
pub(crate) mod peer_types;
pub mod router;
pub mod runtime;

pub use agent::types::{DrainedMessage, PlainMessage, drain_inbox_item};
pub use event_injector::CommsEventInjector;
pub use identity::{IdentityError, Keypair, PubKey, Signature};
pub use inbox::{AdmissionOutcome, DropReason, Inbox, InboxError, InboxSender};
pub use inproc::{InprocPeerInfo, InprocRegistry, InprocSendError};
#[cfg(not(target_arch = "wasm32"))]
pub use io_task::{IoTaskError, handle_connection};
pub use peer_meta::PeerMeta;
pub use router::{CommsConfig, DEFAULT_MAX_MESSAGE_BYTES, Router, SendError};
#[cfg(not(target_arch = "wasm32"))]
pub use transport::codec::{EnvelopeFrame, TransportCodec};
pub use transport::{PeerAddr, TransportError};
pub use trust::{TrustEntry, TrustError, TrustResolveError, TrustStore, TrustedPeer, TrustedPeers};
pub use types::{Envelope, InboxItem, MessageKind, Status};

// Re-export high-level components
pub use runtime::comms_bootstrap::{
    CommsAdvertise, CommsBootstrap, CommsBootstrapError, CommsBootstrapMode, ParentCommsContext,
    PreparedComms,
};
pub use runtime::comms_config::CoreCommsConfig;
#[cfg(not(target_arch = "wasm32"))]
pub use runtime::comms_config::ResolvedCommsConfig;
pub use runtime::comms_runtime::{
    CommsRuntime, CommsRuntimeError, CommsToolMaterial, PeerRequestResponseAuthority,
};

pub use agent::CommsAgent;
pub use agent::dispatcher::{
    CommsToolDispatcher, DynCommsToolDispatcher, NoOpDispatcher, comms_tool_defs, wrap_with_comms,
};
pub use mcp::tools::{
    RuntimeCommsCommandHandle, ToolContext, comms_tool_unavailable_reason, handle_tools_call,
    handle_tools_call_with_context, tools_list,
};

// Capability registration
inventory::submit! {
    meerkat_capabilities::CapabilityRegistration {
        id: meerkat_capabilities::CapabilityId::Comms,
        description: "Inter-agent communication: send, request, response, list peers + keep-alive",
        scope: meerkat_capabilities::CapabilityScope::Universal,
        requires_feature: Some("comms"),
        prerequisites: &[],
        status_resolver: None,
    }
}

// Skill registration
inventory::submit! {
    meerkat_skills::SkillRegistration {
        id: "multi-agent-comms",
        name: "Multi-Agent Comms",
        description: "Setting up keep-alive, peer trust, send vs request/response patterns",
        scope: meerkat_core::skills::SkillScope::Builtin,
        requires_capabilities: &["comms"],
        body: include_str!("../skills/multi-agent-comms/SKILL.md"),
        extensions: &[],
    }
}

/// Confirm keep-alive mode availability when the comms crate is compiled in.
///
/// This function is intentionally a passthrough — its existence in the
/// dependency graph *is* the validation. When `meerkat-comms` is linked,
/// comms is available and keep-alive mode can be enabled. The feature-gate check
/// lives in `meerkat::surface::resolve_keep_alive()`, which calls this
/// function under `#[cfg(feature = "comms")]` and returns an error under
/// `#[cfg(not(feature = "comms"))]`.
///
/// This two-layer design avoids duplicating the `cfg` check in every
/// surface crate.
pub fn validate_keep_alive(requested: bool) -> Result<bool, String> {
    Ok(requested)
}
