use crate::{
    core::{
        actually_used_field::ActuallyUsedField,
        bounds::FieldBounds,
        circuits::traits::arithmetic_circuit::ArithmeticCircuit,
        expressions::expr::EvalFailure,
        global_value::value::FieldValue,
    },
    utils::used_field::UsedField,
};

#[derive(Debug, Clone)]
pub struct ZeroCircuit;

impl<F: UsedField> ArithmeticCircuit<F> for ZeroCircuit {
    fn eval(&self, x: Vec<F>) -> Result<Vec<F>, EvalFailure> {
        let n = x.len();
        Ok(vec![F::ZERO; n])
    }

    fn bounds(&self, bounds: Vec<FieldBounds<F>>) -> Vec<FieldBounds<F>> {
        let n = bounds.len();
        vec![FieldBounds::new(F::ZERO, F::ZERO); n]
    }

    fn run(&self, vals: Vec<FieldValue<F>>) -> Vec<FieldValue<F>>
    where
        F: ActuallyUsedField,
    {
        let n = vals.len();
        vec![F::ZERO.into(); n]
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    use crate::{
        core::circuits::traits::arithmetic_circuit::tests::TestedArithmeticCircuit,
        ArcisField,
    };
    use rand::Rng;
    impl TestedArithmeticCircuit<ArcisField> for ZeroCircuit {
        fn gen_desc<R: Rng + ?Sized>(_rng: &mut R) -> Self {
            ZeroCircuit
        }

        fn gen_n_inputs<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
            let mut n_inputs = 0;
            while rng.gen_bool(0.875) {
                n_inputs += 1;
            }
            n_inputs
        }
    }
    #[test]
    fn tested() {
        ZeroCircuit::test(64, 4)
    }
}
