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

use crate::constants::{ATTRIBUTES, AUTHENTICATION, PAYLOAD, VARS};
use crate::input::Format;
use pel::expression::Symbol;
use pel::runtime::{Binding as PelBinding, Context, ValueHandler};
use pel::Reference;
use std::collections::HashSet;

#[derive(Default, Clone, Debug)]
pub(crate) struct InputContext {
    vars: HashSet<String>,
    payload: Vec<Format>,
    attributes: bool,
    authentication: bool,
}

impl InputContext {
    pub fn set_payload_input(&mut self, format: Format) {
        self.payload.push(format);
    }

    pub fn push_var_input(&mut self, input: &str) {
        self.vars.insert(input.to_string());
    }

    pub fn set_attributes_input(&mut self) {
        self.attributes = true;
    }

    pub fn set_authentication_input(&mut self) {
        self.authentication = true;
    }

    pub fn vars(&self) -> &HashSet<String> {
        &self.vars
    }

    pub fn format(&self) -> &[Format] {
        self.payload.as_ref()
    }

    pub fn attributes(&self) -> bool {
        self.attributes
    }

    pub fn authentication(&self) -> bool {
        self.authentication
    }
}

fn signal_binding(present: bool) -> PelBinding {
    match present {
        true => PelBinding::Pending,
        false => PelBinding::Unknown,
    }
}

impl Context for InputContext {
    fn resolve(&self, symbol: &Symbol) -> PelBinding {
        match symbol.as_str() {
            PAYLOAD => signal_binding(!self.payload.is_empty()),
            VARS => signal_binding(!self.vars.is_empty()),
            ATTRIBUTES => signal_binding(self.attributes),
            AUTHENTICATION => signal_binding(self.authentication),
            _ => PelBinding::Unknown,
        }
    }
    fn value_handler(&self, _reference: Reference) -> Option<&dyn ValueHandler> {
        None
    }
}