//! Entropyk Python bindings.
//!
//! This crate provides Python wrappers for the Entropyk thermodynamic
//! simulation library via PyO3 + Maturin.

// Pre-existing lint debt accumulated before CI was introduced.
#![allow(deprecated)]
#![allow(dead_code)]
#![allow(clippy::too_many_arguments)]

use pyo3::prelude::*;

pub(crate) mod components;
pub(crate) mod errors;
pub(crate) mod solver;
pub(crate) mod types;

/// Python module: ``import entropyk``
#[pymodule]
fn entropyk(m: &Bound<'_, PyModule>) -> PyResult<()> {
    // Register exceptions first
    errors::register_exceptions(m)?;

    // Core types
    m.add_class::<types::PyPressure>()?;
    m.add_class::<types::PyTemperature>()?;
    m.add_class::<types::PyEnthalpy>()?;
    m.add_class::<types::PyMassFlow>()?;
    m.add_class::<types::PyConcentration>()?;
    m.add_class::<types::PyVolumeFlow>()?;
    m.add_class::<types::PyRelativeHumidity>()?;
    m.add_class::<types::PyVaporQuality>()?;

    // Components
    m.add_class::<components::PyCompressor>()?;
    m.add_class::<components::PyScrewEconomizerCompressor>()?;
    m.add_class::<components::PyCondenser>()?;
    m.add_class::<components::PyEvaporator>()?;
    m.add_class::<components::PyEconomizer>()?;
    m.add_class::<components::PyExpansionValve>()?;
    m.add_class::<components::PyPipe>()?;
    m.add_class::<components::PyPump>()?;
    m.add_class::<components::PyFan>()?;
    m.add_class::<components::PyFlowSplitter>()?;
    m.add_class::<components::PyFlowMerger>()?;
    m.add_class::<components::PyFlowSource>()?;
    m.add_class::<components::PyFlowSink>()?;
    m.add_class::<components::PyRefrigerantSource>()?;
    m.add_class::<components::PyRefrigerantSink>()?;
    m.add_class::<components::PyBrineSource>()?;
    m.add_class::<components::PyBrineSink>()?;
    m.add_class::<components::PyAirSource>()?;
    m.add_class::<components::PyAirSink>()?;
    m.add_class::<components::PyCapillaryTube>()?;
    m.add_class::<components::PyFanCoilUnit>()?;
    m.add_class::<components::PyOperationalState>()?;

    // Solver
    m.add_class::<solver::PySystem>()?;
    m.add_class::<solver::PyNewtonConfig>()?;
    m.add_class::<solver::PyPicardConfig>()?;
    m.add_class::<solver::PyFallbackConfig>()?;
    m.add_class::<solver::PyConvergedState>()?;
    m.add_class::<solver::PyConvergenceStatus>()?;
    m.add_class::<solver::PyConstraint>()?;
    m.add_class::<solver::PyBoundedVariable>()?;
    m.add_class::<solver::PyConvergenceCriteria>()?;
    m.add_class::<solver::PyJacobianFreezingConfig>()?;
    m.add_class::<solver::PyTimeoutConfig>()?;
    m.add_class::<solver::PySolverStrategy>()?;

    Ok(())
}
