1use std::{collections::{HashMap, HashSet}, sync::{Arc, RwLock}};
2use log::{debug, error, trace, warn};
3use serde::de::DeserializeOwned;
4use serde_json::Value;
5use crate::{ParserError, WorldInfoNode, WorldInfoProcessor};
6use std::fmt::Debug;
7
8pub struct WorldInfoRegistry<P: PluginBridge + 'static> {
9 processor_factories: RwLock<HashMap<String, Box<dyn WorldInfoProcessorFactory<P>>>>,
10 plugin_bridge: Arc<P>,
11 variables: HashMap<String, serde_json::Value>,
12 activation_stack: HashSet<String>
13}
14
15pub struct ScopedRegistry<'a, P: PluginBridge + 'static> {
16 inner: &'a mut WorldInfoRegistry<P>,
17 allowed_scopes: &'a [String],
18 scope_id: String
19}
20
21impl <'a, P: PluginBridge + 'static> ScopedRegistry<'a, P> {
22 pub fn instantiate_processor(&self, name: &str, props: &serde_json::Value) -> Option<Box<dyn WorldInfoNode>> {
23 self.inner.instantiate_processor(name, props)
24 }
25}
26
27pub trait VariableResolver {
28 fn get_variable(&self, name: &str, loop_context: Option<&HashMap<String, Value>>) -> Result<Value, ParserError>;
30 fn insert_variable(&mut self, name: &str, value: Value) -> Result<(), ParserError>;
32 fn update_variable(&mut self, name: &str, value: Value) -> Result<(), ParserError>;
34 fn resolve_scope(&self, name: &str) -> Result<(String, String), ParserError>;
36}
37
38pub trait ActivationResolver {
39 fn push_activation(&mut self, id: &str) -> Result<(), ParserError>;
40}
41
42impl<'a, P: PluginBridge> VariableResolver for ScopedRegistry<'a, P> {
43 fn get_variable(&self, full_name: &str, loop_context: Option<&HashMap<String, Value>>) -> Result<Value, ParserError> {
44 trace!("ScopedRegistry::get_variable: full_name='{}', loop_context is {}", full_name, if loop_context.is_some() { "Some" } else { "None" });
45
46 if let Some(context) = loop_context {
48 if !full_name.contains(':') { if let Some(value) = context.get(full_name) {
50 debug!("Found variable '{}' in loop context (unscoped)", full_name);
51 return Ok(value.clone());
52 }
53 trace!("Variable '{}' not found in loop context (unscoped), proceeding to registry lookup.", full_name);
55 } else {
56 match self.resolve_scope(full_name) {
58 Ok((ref scope, ref name)) if scope == &self.scope_id => {
59 if let Some(value) = context.get(name) {
61 debug!("Found variable '{}:{}' (resolved to local) in loop context", scope, name);
62 return Ok(value.clone());
63 }
64 trace!("Variable '{}:{}' (resolved to local) not found in loop context, proceeding to registry lookup.", scope, name);
65 }
66 Ok((scope, name)) => {
67 trace!("Variable '{}:{}' resolved to non-local scope, ignoring loop context.", scope, name);
69 }
70 Err(_) => {
71 trace!("Could not resolve scope for '{}', proceeding to registry lookup.", full_name);
73 }
74 }
75 }
76 } else {
77 trace!("No loop context provided for variable lookup '{}'.", full_name);
78 }
79
80 let (scope, name) = self.resolve_scope(full_name)?;
82 trace!("Registry lookup: Resolved scope='{}', name='{}'", scope, name);
83 if !self.allowed_scopes.contains(&scope) {
84 error!("Permission denied for scope '{}' trying to access variable '{}'", scope, name);
85 return Err(ParserError::InsufficientPermissions(
86 format!("No access to scope `{}`", scope)
87 ));
88 }
89 let key = format!("{}:{}", scope, name);
90 trace!("Looking up key '{}' in inner variables", key);
91 self.inner.variables .get(&key)
93 .cloned()
94 .ok_or_else(|| {
95 warn!("Variable '{}' not found in registry (key: '{}')", name, key);
96 ParserError::UndefinedVariable(name) })
98 }
99
100 fn resolve_scope(&self, name: &str) -> Result<(String, String), ParserError> {
103 let (scope, name_part) = name.split_once(':').ok_or_else(|| {
104 trace!("Resolving unscoped name '{}' as local to scope '{}'", name, self.scope_id);
106 (self.scope_id.clone(), name.to_string())
107 })
108 .map_err(|_| ParserError::Evaluation(format!("Invalid variable name: {}", name)))?;
109
110 match scope {
111 "entry" | "local" => Ok((self.scope_id.clone(), name_part.to_string())),
113 _ => Ok((scope.to_string(), name_part.to_string()))
115 }
116 }
117
118 fn insert_variable(&mut self, full_name: &str, value: Value) -> Result<(), ParserError> {
119 let (scope, name) = self.resolve_scope(full_name)?;
120 let key = format!("{}:{}", scope, name);
121 trace!("ScopedRegistry::insert_variable: key='{}'", key);
122
123 match scope.as_str() {
124 "global" => {
125 if self.inner.variables.contains_key(&key) {
126 Err(ParserError::VariableAlreadyExists(name))
127 } else {
128 self.inner.variables.insert(key, value); Ok(())
130 }
131 }
132 _ => {
133 if !self.allowed_scopes.contains(&scope) {
135 error!("Permission denied to insert into scope '{}' for variable '{}'", scope, name);
136 Err(ParserError::InsufficientPermissions(
137 format!("No permission to insert into scope `{}`", scope)
138 ))
139 } else if self.inner.variables.contains_key(&key) {
140 error!("Variable '{}' already exists in scope '{}'", name, scope);
141 Err(ParserError::VariableAlreadyExists(name))
142 } else {
143 debug!("Inserting variable '{}' into scope '{}'", name, scope);
144 self.inner.variables.insert(key, value);
145 Ok(())
146 }
147 }
148 }
149 }
150
151 fn update_variable(&mut self, full_name: &str, value: Value) -> Result<(), ParserError> {
152 let (scope, name) = self.resolve_scope(full_name)?;
153 trace!("ScopedRegistry::update_variable: scope='{}', name='{}'", scope, name);
154
155 if scope != "global" && !self.allowed_scopes.contains(&scope) {
157 error!("Permission denied to update variable in scope '{}' for variable '{}'", scope, name);
158 return Err(ParserError::InsufficientPermissions(
159 format!("No permission to update in scope `{}`", scope)
160 ));
161 }
162
163 let key = format!("{}:{}", scope, name);
164 if let Some(slot) = self.inner.variables.get_mut(&key) {
165 debug!("Updating variable '{}' in scope '{}'", name, scope);
166 *slot = value;
167 Ok(())
168 } else {
169 error!("Attempted to update undefined variable '{}' in scope '{}'", name, scope);
170 Err(ParserError::UndefinedVariable(name))
171 }
172 }
173}
174
175impl<P: PluginBridge + 'static> VariableResolver for WorldInfoRegistry<P> {
176 fn get_variable(&self, name: &str, _loop_context: Option<&HashMap<String, Value>>) -> Result<Value, ParserError> {
178 trace!("WorldInfoRegistry::get_variable: name='{}', loop_context ignored", name);
179 let (scope, name_part) = self.resolve_scope(name)?; let key = format!("{}:{}", scope, name_part);
181 trace!("WorldInfoRegistry lookup: key='{}'", key);
182 self.variables
183 .get(&key)
184 .cloned()
185 .ok_or_else(|| {
186 warn!("WorldInfoRegistry: Variable '{}' (key: '{}') not found.", name_part, key);
187 ParserError::UndefinedVariable(name_part)
188 })
189 }
190
191 fn insert_variable(&mut self, name: &str, value: Value) -> Result<(), ParserError> {
195 let (scope, name_part) = self.resolve_scope(name)?;
196 let key = format!("{}:{}", scope, name_part);
197 trace!("WorldInfoRegistry::insert_variable: key='{}'", key);
198
199 if self.variables.contains_key(&key) {
200 error!("WorldInfoRegistry: Variable '{}' already exists in scope '{}'", name_part, scope);
201 Err(ParserError::VariableAlreadyExists(name_part))
202 } else {
203 debug!("WorldInfoRegistry: Inserting variable '{}' into scope '{}'", name_part, scope);
204 self.variables.insert(key, value);
205 Ok(())
206 }
207 }
208
209 fn update_variable(&mut self, name: &str, value: Value) -> Result<(), ParserError> {
210 let (scope, name_part) = self.resolve_scope(name)?;
211 let key = format!("{}:{}", scope, name_part);
212 trace!("WorldInfoRegistry::update_variable: key='{}'", key);
213
214 if let Some(slot) = self.variables.get_mut(&key) {
215 debug!("WorldInfoRegistry: Updating variable '{}' in scope '{}'", name_part, scope);
216 *slot = value;
217 Ok(())
218 } else {
219 error!("WorldInfoRegistry: Attempted to update undefined variable '{}' in scope '{}'", name_part, scope);
220 Err(ParserError::UndefinedVariable(name_part))
221 }
222 }
223
224 fn resolve_scope(&self, name: &str) -> Result<(String, String), ParserError> {
225 let (scope, name_part) = name.split_once(':').ok_or_else(|| {
227 error!("WorldInfoRegistry::resolve_scope: Unscoped variable access attempted: '{}'. Only 'global:' scope allowed.", name);
228 ParserError::InsufficientPermissions(format!("WorldInfoRegistry cannot access unscoped variable: {}. Use 'global:' prefix.", name))
229 })?;
230
231 match scope {
232 "global" => Ok(("global".to_string(), name_part.to_string())),
233 _ => {
234 error!("WorldInfoRegistry::resolve_scope: Non-global scope access attempted: '{}:{}'. Only 'global:' scope allowed.", scope, name_part);
235 Err(ParserError::InsufficientPermissions(format!("WorldInfoRegistry cannot access scope '{}'. Use 'global:' prefix.", scope)))
236 }
237 }
238 }
239}
240
241impl<P: PluginBridge + 'static> ActivationResolver for ScopedRegistry<'_, P> {
242 fn push_activation(&mut self, id: &str) -> Result<(), ParserError> {
243 self.inner.push_activation(id)
244 }
245}
246
247impl <P: PluginBridge + 'static> ActivationResolver for WorldInfoRegistry<P> {
248 fn push_activation(&mut self, id: &str) -> Result<(), ParserError> {
249 self.activation_stack.insert(id.to_string());
250 Ok(())
251 }
252}
253
254impl<P: PluginBridge + 'static> WorldInfoRegistry<P> {
255 pub fn new(plugin_bridge: Arc<P>) -> Self {
256 Self {
257 processor_factories: RwLock::new(HashMap::new()),
258 plugin_bridge,
259 variables: HashMap::new(),
260 activation_stack: HashSet::new()
261 }
262 }
263
264 pub fn register_processor(&self, name: &str, factory: Box<dyn WorldInfoProcessorFactory<P>>) {
265 self.processor_factories.write().unwrap().insert(name.to_string(), factory);
266 }
267
268 pub fn register_plugin_processor(&self, author: &str, name: &str) {
269 self.register_processor(format!("weaver.plugin.{}.{}", author, name).as_str(), Box::new(plugin::PluginProcessorFactory));
270 }
271
272 pub fn instantiate_processor(&self, name: &str, props: &serde_json::Value) -> Option<Box<dyn WorldInfoNode>> {
273 let registry = self.processor_factories.read().unwrap();
274 registry.get(name).map(|factory| factory.create(props, &self.plugin_bridge) as Box<dyn WorldInfoNode>)
275 }
276
277 pub fn plugin_bridge(&self) -> &P {
278 &self.plugin_bridge
279 }
280
281 pub fn register_variable(&mut self, var: String, value: serde_json::Value) {
285 self.variables.insert(var, value);
286 }
287
288 pub(crate) fn scoped_registry<'a>(&'a mut self, allowed_scopes: &'a [String], scope_id: String) -> ScopedRegistry<'a, P> {
289 ScopedRegistry { inner: self, allowed_scopes, scope_id }
290 }
291
292 pub(crate) fn activation_stack(&mut self) -> HashSet<String> {
294 let stack = self.activation_stack.clone();
295 self.activation_stack.clear();
296 stack
297 }
298}
299
300pub trait WorldInfoProcessorFactory<P: PluginBridge + 'static>: Send + Sync + 'static {
302 fn create(&self, properties: &serde_json::Value, bridge: &Arc<P>) -> Box<dyn WorldInfoProcessor>;
303}
304
305pub trait PluginBridge: Clone + Debug {
306 type PluginId: Copy + DeserializeOwned + Debug;
307 fn invoke_plugin(&self, plugin_id: Self::PluginId, properties: serde_json::Value) -> Result<String, crate::WorldInfoError>;
308}
309
310pub mod wildcard;
312pub mod rng;
313pub mod plugin;
314
315pub use wildcard::{WildcardProcessor, WildcardProcessorFactory};
317pub use rng::{RngProcessor, RngProcessorFactory};