//! Translation implementations for unary operators

use crate::TranslationRegistry;
use crate::{range_builder::RangeBuilder, utils::direct_unary_operator_translation};
use hamelin_lib::func::defs::{
    UnaryMinus, UnaryPlus, UnaryRangePostfix, UnaryRangePrefix, UnaryRangePrefixInclusive,
};

/// Register all unary operator translations.
pub fn register(registry: &mut TranslationRegistry) {
    // UnaryMinus uses direct unary operator translation (-x)
    registry.register::<UnaryMinus>(direct_unary_operator_translation);

    // UnaryPlus uses direct unary operator translation (+x)
    registry.register::<UnaryPlus>(direct_unary_operator_translation);

    // UnaryRangePrefix: ..x creates a range with upper bound only
    registry.register::<UnaryRangePrefix>(|_, mut bindings| {
        let x = bindings.take()?;
        let rb = RangeBuilder::default()
            .with_end(x.sql, x.typ.to_sql()?)
            .build();
        Ok(rb)
    });

    // UnaryRangePrefixInclusive: ..=x -> ROW(NULL, x)
    // Inclusivity is tracked at the type level (Type::RangeInclusive), not in the SQL value.
    registry.register::<UnaryRangePrefixInclusive>(|_, mut bindings| {
        let x = bindings.take()?;
        let rb = RangeBuilder::default()
            .with_end(x.sql, x.typ.to_sql()?)
            .build();
        Ok(rb)
    });

    // UnaryRangePostfix: x.. creates a range with lower bound only
    registry.register::<UnaryRangePostfix>(|_, mut bindings| {
        let x = bindings.take()?;
        let rb = RangeBuilder::default()
            .with_begin(x.sql, x.typ.to_sql()?)
            .build();
        Ok(rb)
    });
}
