mod bits_and_other;
mod optimize_curve;
mod optimize_field;

use crate::core::{
    compile_passes::compilation_pass::{CompilationPass, LocalCompilationPass},
    expressions::expr::Expr,
    ir::IntermediateRepresentation,
    ir_builder::IRBuilder,
};

/// Optimizes the already-built circuits.
#[derive(Default)]
pub struct Optimizer {
    expr_store: IRBuilder,
}
impl Optimizer {
    pub fn optimize(old_ir: IntermediateRepresentation) -> IntermediateRepresentation {
        Self::make_and_run(old_ir)
    }
}

impl LocalCompilationPass for Optimizer {
    fn expr_store(&mut self) -> &mut IRBuilder {
        &mut self.expr_store
    }

    fn transform(&mut self, expr: Expr<usize>, is_plaintext: bool) -> Expr<usize> {
        match expr {
            Expr::Scalar(e) => self.optimize_field_expr(e, is_plaintext),
            Expr::Bit(e) => self.optimize_bit_expr(e),
            Expr::ScalarConversion(e) => self.optimize_conversion_expr(e),
            Expr::Base(e) => self.optimize_field_expr(e, is_plaintext),
            Expr::BaseConversion(e) => self.optimize_conversion_expr(e),
            Expr::Curve(e) => self.optimize_curve_expr(e),
            Expr::Other(_) => expr,
        }
    }
}
