/*
*   Copyright (c) 2025 Anton Kundenko <singaraiona@gmail.com>
*   All rights reserved.
*
*   Permission is hereby granted, free of charge, to any person obtaining a copy
*   of this software and associated documentation files (the "Software"), to deal
*   in the Software without restriction, including without limitation the rights
*   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*   copies of the Software, and to permit persons to whom the Software is
*   furnished to do so, subject to the following conditions:
*
*   The above copyright notice and this permission notice shall be included in all
*   copies or substantial portions of the Software.
*
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*   SOFTWARE.
*/

//! # Catalyx
//!
//! A reactive streaming runtime built on RayforceDB, inspired by join calculus
//! and chemical reaction models.
//!
//! ## Core Concepts
//!
//! - **Molecule**: A message/event with a typed payload
//! - **Reaction**: A join pattern that matches multiple molecules
//! - **Solution**: A reactive context/namespace
//! - **Catalyst**: A persistent trigger that isn't consumed
//! - **Substrate**: The underlying RayforceDB storage
//!
//! ## Example
//!
//! ```ignore
//! use catalyx::Catalyx;
//!
//! let ctx = Catalyx::new()?;
//!
//! // Define molecules
//! ctx.eval("mol ping(x: int)")?;
//! ctx.eval("mol pong(y: int)")?;
//!
//! // Define a reaction
//! ctx.eval("react ping(a) & pong(b) => (+ a b)")?;
//!
//! // Emit molecules
//! let result = ctx.eval("emit ping(21) pong(21)")?;
//! assert_eq!(result.to_string(), "42");
//! ```

pub mod error;

pub use error::{CatalyxError, Result};

/// Catalyx runtime context.
///
/// Wraps RayforceDB and provides the reactive streaming layer
/// with molecules, reactions, and solutions.
pub struct Catalyx {
    _placeholder: (),
}

impl Catalyx {
    /// Create a new Catalyx runtime instance.
    pub fn new() -> Result<Self> {
        Ok(Self { _placeholder: () })
    }

    /// Get the Catalyx version.
    pub fn version() -> &'static str {
        env!("CARGO_PKG_VERSION")
    }

    /// Evaluate a Catalyx expression.
    pub fn eval(&self, _input: &str) -> Result<String> {
        // Placeholder - full implementation requires rayforce
        Ok("Catalyx v0.1.0 - placeholder release".to_string())
    }
}

impl Default for Catalyx {
    fn default() -> Self {
        Self::new().expect("Failed to initialize Catalyx runtime")
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_create_runtime() {
        let ctx = Catalyx::new();
        assert!(ctx.is_ok());
    }

    #[test]
    fn test_version() {
        assert!(!Catalyx::version().is_empty());
    }
}
