package content import ( "fmt" "log" "os" "path/filepath" "strings" "sync" "github.com/insertr/insertr/internal/engine" ) // SiteConfig represents configuration for a registered site type SiteConfig struct { SiteID string `yaml:"site_id"` Path string `yaml:"path"` // Served path (enhanced output) SourcePath string `yaml:"source_path"` // Source path (for enhancement) Domain string `yaml:"domain,omitempty"` AutoEnhance bool `yaml:"auto_enhance"` } // SiteManager handles registration and enhancement of static sites type SiteManager struct { sites map[string]*SiteConfig enhancer *Enhancer mutex sync.RWMutex devMode bool contentClient engine.ContentClient authProvider *engine.AuthProvider } // NewSiteManager creates a new site manager func NewSiteManager(contentClient engine.ContentClient, devMode bool) *SiteManager { return &SiteManager{ sites: make(map[string]*SiteConfig), enhancer: NewDefaultEnhancer(contentClient, ""), // siteID will be set per operation devMode: devMode, contentClient: contentClient, authProvider: &engine.AuthProvider{Type: "mock"}, // default } } // NewSiteManagerWithAuth creates a new site manager with auth provider func NewSiteManagerWithAuth(contentClient engine.ContentClient, devMode bool, authProvider *engine.AuthProvider) *SiteManager { if authProvider == nil { authProvider = &engine.AuthProvider{Type: "mock"} } return &SiteManager{ sites: make(map[string]*SiteConfig), contentClient: contentClient, authProvider: authProvider, devMode: devMode, } } // RegisterSite adds a site to the manager func (sm *SiteManager) RegisterSite(config *SiteConfig) error { sm.mutex.Lock() defer sm.mutex.Unlock() // Validate site configuration if config.SiteID == "" { return fmt.Errorf("site_id is required") } if config.Path == "" { return fmt.Errorf("path is required for site %s", config.SiteID) } // Check if path exists, auto-create enhancement directories if _, err := os.Stat(config.Path); os.IsNotExist(err) { // Auto-create directory if it appears to be an enhancement target if strings.HasSuffix(config.Path, "_enhanced") { log.Printf("📁 Creating enhancement directory: %s", config.Path) if err := os.MkdirAll(config.Path, 0755); err != nil { return fmt.Errorf("failed to create enhancement directory %s: %w", config.Path, err) } } else { return fmt.Errorf("site path does not exist: %s", config.Path) } } // Convert to absolute path absPath, err := filepath.Abs(config.Path) if err != nil { return fmt.Errorf("failed to resolve absolute path for %s: %w", config.Path, err) } config.Path = absPath sm.sites[config.SiteID] = config log.Printf("📁 Registered site %s at %s", config.SiteID, config.Path) return nil } // RegisterSites bulk registers multiple sites from configuration func (sm *SiteManager) RegisterSites(configs []*SiteConfig) error { for _, config := range configs { if err := sm.RegisterSite(config); err != nil { return fmt.Errorf("failed to register site %s: %w", config.SiteID, err) } } return nil } // GetSite returns a registered site configuration func (sm *SiteManager) GetSite(siteID string) (*SiteConfig, bool) { sm.mutex.RLock() defer sm.mutex.RUnlock() site, exists := sm.sites[siteID] return site, exists } // GetAllSites returns all registered sites func (sm *SiteManager) GetAllSites() map[string]*SiteConfig { sm.mutex.RLock() defer sm.mutex.RUnlock() // Return a copy to prevent external modification result := make(map[string]*SiteConfig) for id, site := range sm.sites { result[id] = site } return result } // IsAutoEnhanceEnabled checks if a site has auto-enhancement enabled func (sm *SiteManager) IsAutoEnhanceEnabled(siteID string) bool { sm.mutex.RLock() defer sm.mutex.RUnlock() site, exists := sm.sites[siteID] return exists && site.AutoEnhance } // EnhanceSite performs enhancement from source to output directory func (sm *SiteManager) EnhanceSite(siteID string) error { sm.mutex.RLock() site, exists := sm.sites[siteID] sm.mutex.RUnlock() if !exists { return fmt.Errorf("site %s is not registered", siteID) } // Use source path if available, otherwise use main path (for backwards compatibility) sourcePath := site.SourcePath if sourcePath == "" { sourcePath = site.Path } outputPath := site.Path log.Printf("🔄 Enhancing site %s from %s to %s", siteID, sourcePath, outputPath) // Create output directory if it doesn't exist if err := os.MkdirAll(outputPath, 0755); err != nil { return fmt.Errorf("failed to create output directory %s: %w", outputPath, err) } // Create enhancer with auth provider for this operation defaultConfig := EnhancementConfig{ Discovery: DiscoveryConfig{ Enabled: true, Aggressive: false, Containers: true, Individual: true, }, ContentInjection: true, GenerateIDs: true, } enhancer := NewEnhancerWithAuth(sm.contentClient, siteID, defaultConfig, sm.authProvider) // Perform enhancement from source to output if err := enhancer.EnhanceDirectory(sourcePath, outputPath); err != nil { return fmt.Errorf("failed to enhance site %s: %w", siteID, err) } log.Printf("✅ Successfully enhanced site %s", siteID) return nil } // EnhanceAllSites enhances all registered sites that have auto-enhancement enabled func (sm *SiteManager) EnhanceAllSites() error { sm.mutex.RLock() sites := make([]*SiteConfig, 0, len(sm.sites)) for _, site := range sm.sites { if site.AutoEnhance { sites = append(sites, site) } } sm.mutex.RUnlock() var errors []error for _, site := range sites { if err := sm.EnhanceSite(site.SiteID); err != nil { errors = append(errors, err) } } if len(errors) > 0 { return fmt.Errorf("enhancement failed for some sites: %v", errors) } return nil } // GetStats returns statistics about registered sites func (sm *SiteManager) GetStats() map[string]interface{} { sm.mutex.RLock() defer sm.mutex.RUnlock() autoEnhanceCount := 0 for _, site := range sm.sites { if site.AutoEnhance { autoEnhanceCount++ } } return map[string]interface{}{ "total_sites": len(sm.sites), "auto_enhance_sites": autoEnhanceCount, } }