use crate::core::expressions::field_expr::PlayerId;
use core_utils::circuit::AlgebraicType;
use primitives::algebra::elliptic_curve::Curve25519Ristretto;
use serde::{Deserialize, Serialize};

pub mod bit_expr;
pub mod circuit;
pub mod conversion_expr;
pub mod curve_expr;
pub mod domain;
pub mod expr;
pub mod expr_macros;
pub mod field_expr;
pub mod macro_uses;
pub mod other_expr;
#[cfg(test)]
pub mod random_expr;

/// The kind of input.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum InputKind {
    Secret,
    SecretFromPlayer(PlayerId),
    Plaintext,
}
impl InputKind {
    pub fn is_plaintext(&self) -> bool {
        match self {
            InputKind::Secret => false,
            InputKind::SecretFromPlayer(_) => false,
            InputKind::Plaintext => true,
        }
    }
    pub fn to_input(
        self,
        algebraic_type: core_utils::circuit::AlgebraicType,
    ) -> core_utils::circuit::Input<Curve25519Ristretto> {
        let batched = core_utils::circuit::Batched::No;
        match self {
            InputKind::Secret => core_utils::circuit::Input::Share {
                algebraic_type,
                batched,
            },
            InputKind::SecretFromPlayer(i) => core_utils::circuit::Input::SecretPlaintext {
                inputer: i,
                algebraic_type,
                batched,
            },
            InputKind::Plaintext => match algebraic_type {
                AlgebraicType::BaseField => {
                    core_utils::circuit::Input::BaseField(core_utils::circuit::Plaintext::Input(1))
                }
                AlgebraicType::ScalarField => {
                    core_utils::circuit::Input::Scalar(core_utils::circuit::Plaintext::Input(1))
                }
                AlgebraicType::Point => {
                    core_utils::circuit::Input::Point(core_utils::circuit::Plaintext::Input(1))
                }
                AlgebraicType::Bit => {
                    core_utils::circuit::Input::Bit(core_utils::circuit::Plaintext::Input(1))
                }
                AlgebraicType::Mersenne107 => core_utils::circuit::Input::Mersenne107(
                    core_utils::circuit::Plaintext::Input(1),
                ),
            },
        }
    }
}
