use crate::planner::{MemberSymbol, TraversalVisitor};
use cubenativeutils::CubeError;
use std::rc::Rc;

pub struct HasCumulativeMembersCollector {
    pub has_cumulative_members: bool,
}

impl HasCumulativeMembersCollector {
    pub fn new() -> Self {
        Self {
            has_cumulative_members: false,
        }
    }

    pub fn extract_result(self) -> bool {
        self.has_cumulative_members
    }
}

impl TraversalVisitor for HasCumulativeMembersCollector {
    type State = ();
    fn on_node_traverse(
        &mut self,
        node: &Rc<MemberSymbol>,
        _: &Self::State,
    ) -> Result<Option<Self::State>, CubeError> {
        if let MemberSymbol::Measure(s) = node.as_ref() {
            if s.is_rolling_window() {
                self.has_cumulative_members = true;
            }
        };
        if self.has_cumulative_members {
            Ok(None)
        } else {
            Ok(Some(()))
        }
    }
}

pub fn has_cumulative_members(node: &Rc<MemberSymbol>) -> Result<bool, CubeError> {
    let mut visitor = HasCumulativeMembersCollector::new();
    visitor.apply(node, &())?;
    Ok(visitor.extract_result())
}
