use std::rc::Rc;

use crate::environment::Environment;

use super::{Error, Node, NodeEnum, Precedence, constant::ConstantValue};

#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub struct Range {
    pub from: ConstantValue,
    pub to: ConstantValue,
}

impl Node for Range {
    fn evaluate(&self, _: &mut Environment) -> Result<Rc<NodeEnum>, Error> {
        Ok(Rc::new(self.clone().into()))
    }

    fn as_string(&self, _: Option<&Environment>) -> String {
        format!(
            "{}..{}",
            self.from
                .to_string_radix(10, Some(8))
                .trim_end_matches('0')
                .trim_end_matches('.')
                .to_string(),
            self.to
                .to_string_radix(10, Some(8))
                .trim_end_matches('0')
                .trim_end_matches('.')
                .to_string()
        )
    }

    fn precedence(&self) -> Precedence {
        Precedence::Primary
    }
}

impl Range {
    pub fn new(from: ConstantValue, to: ConstantValue) -> Rc<NodeEnum> {
        Rc::new(Self { from, to }.into())
    }
}
