use crate::decision_variable::VariableID;

/// Error types that can occur during substitution operations.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum SubstitutionError {
    /// Error indicating that a recursive assignment was attempted.
    #[error("Recursive assignment detected: variable {var_id} cannot be assigned to a function that depends on itself")]
    RecursiveAssignment { var_id: VariableID },

    /// Error indicating that a cycle was detected in the assignment graph.
    #[error("Cyclic assignment detected: circular dependency found in variable assignments")]
    CyclicAssignmentDetected,

    /// Substituting an indicator variable is not yet supported.
    /// Fixing it to 1 would convert to a regular constraint, fixing to 0 would remove it.
    #[error("Cannot substitute indicator variable {indicator_variable:?} of indicator constraint {constraint_id:?}")]
    IndicatorVariableSubstitution {
        indicator_variable: VariableID,
        constraint_id: crate::indicator_constraint::IndicatorConstraintID,
    },

    /// Substituting a one-hot variable would change the constraint type.
    #[error("Cannot substitute variable {variable:?} of one-hot constraint {constraint_id:?}")]
    OneHotVariableSubstitution {
        variable: VariableID,
        constraint_id: crate::one_hot_constraint::OneHotConstraintID,
    },

    /// Substituting a SOS1 variable would change the constraint type.
    #[error("Cannot substitute variable {variable:?} of SOS1 constraint {constraint_id:?}")]
    Sos1VariableSubstitution {
        variable: VariableID,
        constraint_id: crate::sos1_constraint::Sos1ConstraintID,
    },
}
