Documentation
// Copyright (c) 2026, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

use crate::constants::{VARS, VARS_REFERENCE};
use crate::context::input::InputContext;
use crate::context::map::MapContext;
use crate::Value;
use pel::expression::Symbol;
use pel::runtime::value::Value as PelValue;
use pel::runtime::{Binding as PelBinding, Context, ValueHandler};
use pel::Reference;
use std::collections::HashMap;

pub(crate) struct VarsContext<'a> {
    input_context: &'a InputContext,
    pending_vars: MapContext<String>,
}

impl<'a> VarsContext<'a> {
    pub fn new(input_context: &'a InputContext, vars: HashMap<String, Value>) -> Self {
        let vars = vars.into_iter().map(|(k, v)| (k, v.into_pel())).collect();
        Self {
            input_context,
            pending_vars: MapContext::new(vars),
        }
    }
}

impl Context for VarsContext<'_> {
    fn resolve(&self, symbol: &Symbol) -> PelBinding {
        match !self.input_context.vars().is_empty() && symbol.as_str() == VARS {
            true => PelBinding::Available(PelValue::reference(VARS_REFERENCE)),
            false => PelBinding::Unknown,
        }
    }

    fn value_handler(&self, reference: Reference) -> Option<&dyn ValueHandler> {
        match reference {
            VARS_REFERENCE => Some(&self.pending_vars),
            _ => None,
        }
    }
}