package runner import ( "fmt" "strings" "sync" luajit "git.sharkk.net/Sky/LuaJIT-to-Go" "git.sharkk.net/Sky/Moonshark/core/logger" ) // CoreModuleRegistry manages the initialization and reloading of core modules type CoreModuleRegistry struct { modules map[string]StateInitFunc mu sync.RWMutex debug bool } // NewCoreModuleRegistry creates a new core module registry func NewCoreModuleRegistry() *CoreModuleRegistry { return &CoreModuleRegistry{ modules: make(map[string]StateInitFunc), debug: false, } } // EnableDebug turns on debug logging func (r *CoreModuleRegistry) EnableDebug() { r.debug = true } // debugLog prints debug messages if enabled func (r *CoreModuleRegistry) debugLog(format string, args ...interface{}) { if r.debug { logger.Debug("[CoreModuleRegistry] "+format, args...) } } // Register adds a module to the registry func (r *CoreModuleRegistry) Register(name string, initFunc StateInitFunc) { r.mu.Lock() defer r.mu.Unlock() r.modules[name] = initFunc r.debugLog("Registered module: %s", name) } // Initialize initializes all registered modules func (r *CoreModuleRegistry) Initialize(state *luajit.State) error { r.mu.RLock() defer r.mu.RUnlock() r.debugLog("Initializing all modules...") // Get all module init functions initFuncs := r.getInitFuncs() // Initialize modules one by one to better track issues for name, initFunc := range initFuncs { r.debugLog("Initializing module: %s", name) if err := initFunc(state); err != nil { r.debugLog("Failed to initialize module %s: %v", name, err) return fmt.Errorf("failed to initialize module %s: %w", name, err) } r.debugLog("Module %s initialized successfully", name) } r.debugLog("All modules initialized successfully") return nil } // getInitFuncs returns all module init functions func (r *CoreModuleRegistry) getInitFuncs() map[string]StateInitFunc { funcs := make(map[string]StateInitFunc, len(r.modules)) for name, initFunc := range r.modules { funcs[name] = initFunc } return funcs } // InitializeModule initializes a specific module func (r *CoreModuleRegistry) InitializeModule(state *luajit.State, name string) error { r.mu.RLock() defer r.mu.RUnlock() initFunc, ok := r.modules[name] if !ok { r.debugLog("Module not found: %s", name) return nil // Module not found, no error } r.debugLog("Reinitializing module: %s", name) return initFunc(state) } // ModuleNames returns a list of all registered module names func (r *CoreModuleRegistry) ModuleNames() []string { r.mu.RLock() defer r.mu.RUnlock() names := make([]string, 0, len(r.modules)) for name := range r.modules { names = append(names, name) } return names } // MatchModuleName checks if a file path corresponds to a registered module func (r *CoreModuleRegistry) MatchModuleName(modName string) (string, bool) { r.mu.RLock() defer r.mu.RUnlock() // Exact match if _, ok := r.modules[modName]; ok { return modName, true } // Check if the module name ends with a registered module for name := range r.modules { if strings.HasSuffix(modName, "."+name) { return name, true } } return "", false } // Global registry instance var GlobalRegistry = NewCoreModuleRegistry() // Initialize global registry with core modules func init() { GlobalRegistry.EnableDebug() // Enable debugging by default GlobalRegistry.Register("http", HTTPModuleInitFunc()) GlobalRegistry.Register("cookie", CookieModuleInitFunc()) logger.Debug("[CoreModuleRegistry] Core modules registered in init()") } // RegisterCoreModule is a helper to register a core module // with the global registry func RegisterCoreModule(name string, initFunc StateInitFunc) { GlobalRegistry.Register(name, initFunc) }