package artifacts import ( "fmt" "strings" "gitea.maximumdirect.net/eric/narratio/internal/config" "gitea.maximumdirect.net/eric/narratio/internal/manifest" ) // ResolveArchiveBucket resolves archive bucket identity with manifest-first precedence. func ResolveArchiveBucket(cfg *config.Config, m *manifest.Manifest) string { if m != nil && strings.TrimSpace(m.S3Bucket) != "" { return strings.TrimSpace(m.S3Bucket) } if cfg == nil || cfg.Pipeline == nil || cfg.Pipeline.Storage.S3 == nil { return "" } return strings.TrimSpace(cfg.Pipeline.Storage.S3.Bucket) } // ResolveArchiveSessionPrefix resolves archive session prefix with manifest-first precedence. func ResolveArchiveSessionPrefix(cfg *config.Config, m *manifest.Manifest) (string, error) { if m != nil && strings.TrimSpace(m.S3SessionPrefix) != "" { return strings.TrimSpace(m.S3SessionPrefix), nil } if cfg == nil || cfg.Session == nil || cfg.Pipeline == nil { return "", fmt.Errorf("resolved config is required") } sessionID := strings.TrimSpace(cfg.Session.SessionID) if sessionID == "" && m != nil { sessionID = strings.TrimSpace(m.SessionID) } campaign := strings.TrimSpace(cfg.Session.Campaign) if campaign == "" && m != nil { campaign = strings.TrimSpace(m.Campaign) } if cfg.Pipeline.Storage.S3 == nil { return "", fmt.Errorf("pipeline.storage.s3 configuration is required") } sessionPrefix := S3SessionPrefix(cfg.Pipeline.Storage.S3.RootPrefix, campaign, sessionID) if strings.TrimSpace(sessionPrefix) == "" { return "", fmt.Errorf("session prefix is required") } return sessionPrefix, nil } // ResolveArchiveRunPrefix resolves archive run prefix with manifest-first precedence. func ResolveArchiveRunPrefix(cfg *config.Config, m *manifest.Manifest) (string, error) { if m != nil { runPrefix := strings.TrimSpace(m.S3RunPrefix) if runPrefix != "" { return runPrefix, nil } } sessionPrefix, err := ResolveArchiveSessionPrefix(cfg, m) if err != nil { return "", err } runID := "" if m != nil { runID = strings.TrimSpace(m.RunID) } if runID == "" { return "", fmt.Errorf("run id is required") } return S3RunPrefix(sessionPrefix, runID), nil } // ResolveArchiveCurrentStateKeys returns current pointer keys for a session prefix. func ResolveArchiveCurrentStateKeys(sessionPrefix string) (manifestKey, runIDKey string) { return S3CurrentManifestKey(sessionPrefix), S3CurrentRunPointerKey(sessionPrefix) }