//! ServiceActivator trait: metadata & channel binding intent for a service (activator).
//! Service trait: async-only business logic component.
//!
//! # Example
//! ```rust
//! use allora_core::{error::Result, service::Service, Exchange, Message};
//! #[derive(Debug)] struct Echo;
//! impl Echo { pub fn new() -> Self { Self } }
//! #[async_trait::async_trait]
//! impl Service for Echo {
//!     async fn process(&self, exchange: &mut Exchange) -> Result<()> {
//!         if let Some(b) = exchange.in_msg.body_text() { exchange.out_msg = Some(Message::from_text(format!("echo:{b}"))); }
//!         Ok(())
//!     }
//! }
//! let svc = Echo::new();
//! let mut ex = Exchange::new(Message::from_text("hi"));
//! tokio::runtime::Runtime::new().unwrap().block_on(async { svc.process(&mut ex).await.unwrap(); });
//! assert_eq!(ex.out_msg.unwrap().body_text(), Some("echo:hi"));
//! ```
//!
//! # Metadata Accessors
//! * `id()` – stable identifier (auto-generated or user supplied).
//! * `from()` / `to()` – declared channel ids for wiring.
//! * `ref_name()` – reference name matching YAML `ref-name` and the `#[service(name=..)]` macro argument (not a file path).
//!
//! # Implementing
//! ```ignore
//! use allora::{service::Service, Exchange, error::Result};
//! struct UppercaseService;
//! impl UppercaseService { pub fn new() -> Self { Self } }
//! #[cfg_attr(feature = "async", async_trait::async_trait)]
//! impl Service for UppercaseService {
//!     async fn process(&self, exchange: &mut Exchange) -> Result<()> {
//!         if let Some(body) = exchange.in_msg.body_text() { exchange.in_msg.set_body_text(body.to_uppercase()); }
//!         Ok(())
//!     }
//! }
//! ```
//! (Single impl with conditional methods; avoids duplication.)
//!
//! # Future Extensions
//! * Error classification (e.g. routing vs transformation).
//! * Lifecycle hooks (`init`, `shutdown`).
//! * Metrics instrumentation via feature flag.
//!
//! This file intentionally provides only the trait; concrete implementations are user-defined
//! or generated by a future service builder.

use crate::{error::Result, Exchange};
use std::fmt::Debug;

/// Internal metadata describing how a service is wired. Users do NOT implement this directly; it is derived from specs.
pub trait ServiceActivator: Send + Sync + Debug {
    fn id(&self) -> &str;
    fn from(&self) -> &str;
    fn to(&self) -> &str;
    fn ref_name(&self) -> &str;
}

#[async_trait::async_trait]
pub trait Service: Send + Sync + Debug {
    async fn process(&self, exchange: &mut Exchange) -> Result<()>;
}
