pub mod facenet;

// Re-export common types and traits
pub use facenet::FaceNetEmbedder;
pub use facenet::{FaceEmbedding, FaceEmbeddingConfig, IntoEmbeddings};

// Convenience type aliases for different backends
pub use facenet::mnn::EmbeddingGenerator as MnnEmbeddingGenerator;
pub use facenet::ort::EmbeddingGenerator as OrtEmbeddingGenerator;

use crate::errors::*;
use ndarray::{Array2, ArrayView4};

pub mod preprocessing {
    use ndarray::*;
    pub fn preprocess(faces: ArrayView4<u8>) -> Array4<f32> {
        let mut owned = faces.as_standard_layout().mapv(|v| v as f32).to_owned();
        owned.axis_iter_mut(Axis(0)).for_each(|mut image| {
            let mean = image.mean().unwrap_or(0.0);
            let std = image.std(0.0);
            if std > 0.0 {
                image.mapv_inplace(|x| (x - mean) / std);
            } else {
                image.mapv_inplace(|x| (x - 127.5) / 128.0)
            }
        });
        owned
    }
}

/// Common trait for face embedding backends - maintained for backward compatibility
pub trait FaceEmbedder {
    /// Generate embeddings for a batch of face images
    fn run_models(&mut self, faces: ArrayView4<u8>) -> Result<Array2<f32>>;
}
