package progress import ( "fmt" "log" "math" "strings" "sync" ) const ( obrimProgressTypeCountable = "countable" obrimProgressTypeUncountable = "uncountable" obrimProgressStateStarted = "started" obrimProgressStateRunning = "running" obrimProgressStateCompleted = "completed" obrimProgressStateCanceled = "canceled" obrimProgressSuccessStarted = "SUCCESS_PROGRESS_STARTED" obrimProgressSuccessRunning = "SUCCESS_PROGRESS_RUNNING" obrimProgressSuccessCompleted = "SUCCESS_PROGRESS_COMPLETED" obrimProgressSuccessCanceled = "SUCCESS_PROGRESS_CANCELED" obrimProgressFailedMisconfigured = "FAILED_PROGRESS_MISCONFIGURED" obrimProgressVisualWidth = 20 ) var ( // obrimProgressMutex protects progress state transitions from corruption. obrimProgressMutex sync.Mutex ) // ObrimProgressConfig defines progress configuration. type ObrimProgressConfig struct { State string `json:"state"` Current int `json:"current,omitempty"` Target int `json:"target,omitempty"` Placeholder string `json:"placeholder,omitempty"` } // ObrimProgressResponse defines standardized utility responses. type ObrimProgressResponse struct { Status bool `json:"status"` Code string `json:"code"` Payload interface{} `json:"payload"` } // ObrimProgressCountablePayload defines countable progress payload. type ObrimProgressCountablePayload struct { State string `json:"state"` Current int `json:"current"` Target int `json:"target"` Percentage int `json:"percentage"` Message string `json:"message"` Visual string `json:"visual"` } // ObrimProgressUncountablePayload defines uncountable progress payload. type ObrimProgressUncountablePayload struct { State string `json:"state"` Placeholder string `json:"placeholder"` Message string `json:"message"` Visual string `json:"visual"` } // ObrimProgress manages lifecycle-aware countable and uncountable progress tracking operations. func ObrimProgress(progressType string, config ObrimProgressConfig) ObrimProgressResponse { obrimProgressMutex.Lock() defer obrimProgressMutex.Unlock() if err := obrimProgressValidate(progressType, config); err != nil { return obrimProgressBuildResponse(false, obrimProgressFailedMisconfigured, nil) } stateCode := obrimProgressHandleState(config.State) switch progressType { case obrimProgressTypeCountable: return obrimProgressCountable(config, stateCode) case obrimProgressTypeUncountable: return obrimProgressUncountable(config, stateCode) default: return obrimProgressBuildResponse(false, obrimProgressFailedMisconfigured, nil) } } // obrimProgressValidate validates input parameters and configuration consistency. func obrimProgressValidate(progressType string, config ObrimProgressConfig) error { switch progressType { case obrimProgressTypeCountable: if config.Target <= 0 { return fmt.Errorf("invalid target") } case obrimProgressTypeUncountable: if strings.TrimSpace(config.Placeholder) == "" { return fmt.Errorf("missing placeholder") } default: return fmt.Errorf("invalid type") } switch config.State { case obrimProgressStateStarted, obrimProgressStateRunning, obrimProgressStateCompleted, obrimProgressStateCanceled: return nil default: return fmt.Errorf("invalid state") } } // obrimProgressHandleState processes lifecycle state transitions. func obrimProgressHandleState(state string) string { switch state { case obrimProgressStateStarted: log.Printf(`{"feature":"progress","event":"started"}`) return obrimProgressSuccessStarted case obrimProgressStateRunning: log.Printf(`{"feature":"progress","event":"running"}`) return obrimProgressSuccessRunning case obrimProgressStateCompleted: log.Printf(`{"feature":"progress","event":"completed"}`) return obrimProgressSuccessCompleted case obrimProgressStateCanceled: log.Printf(`{"feature":"progress","event":"canceled"}`) return obrimProgressSuccessCanceled default: return obrimProgressFailedMisconfigured } } // obrimProgressCountable processes countable progress tracking workflows. func obrimProgressCountable( config ObrimProgressConfig, code string, ) ObrimProgressResponse { percentage := obrimProgressCalculatePercentage( config.Current, config.Target, ) message := obrimProgressGenerateMessage( obrimProgressTypeCountable, config.State, percentage, "", ) visual := obrimProgressGenerateVisual( obrimProgressTypeCountable, percentage, "", ) payload := ObrimProgressCountablePayload{ State: config.State, Current: config.Current, Target: config.Target, Percentage: percentage, Message: message, Visual: visual, } return obrimProgressBuildResponse(true, code, payload) } // obrimProgressCalculatePercentage calculates and normalizes completion percentages. func obrimProgressCalculatePercentage(current int, target int) int { if current < 0 { return 0 } if target <= 0 { return 0 } percentage := int( math.Round( (float64(current) / float64(target)) * 100, ), ) if percentage > 100 { return 100 } if percentage < 0 { return 0 } return percentage } // obrimProgressUncountable processes uncountable progress tracking workflows. func obrimProgressUncountable( config ObrimProgressConfig, code string, ) ObrimProgressResponse { placeholder := obrimProgressResolvePlaceholder( config.Placeholder, ) message := obrimProgressGenerateMessage( obrimProgressTypeUncountable, config.State, 0, placeholder, ) visual := obrimProgressGenerateVisual( obrimProgressTypeUncountable, 0, placeholder, ) payload := ObrimProgressUncountablePayload{ State: config.State, Placeholder: placeholder, Message: message, Visual: visual, } return obrimProgressBuildResponse(true, code, payload) } // obrimProgressResolvePlaceholder validates and prepares placeholder activity messages. func obrimProgressResolvePlaceholder(placeholder string) string { return strings.TrimSpace(placeholder) } // obrimProgressGenerateMessage generates human-readable progress messages. func obrimProgressGenerateMessage( progressType string, state string, percentage int, placeholder string, ) string { switch progressType { case obrimProgressTypeCountable: switch state { case obrimProgressStateStarted: return fmt.Sprintf("Progress started (%d%% complete).", percentage) case obrimProgressStateRunning: return fmt.Sprintf("Progress running (%d%% complete).", percentage) case obrimProgressStateCompleted: return "Progress completed successfully." case obrimProgressStateCanceled: return "Progress canceled." } case obrimProgressTypeUncountable: switch state { case obrimProgressStateStarted: return fmt.Sprintf("Activity started: %s", placeholder) case obrimProgressStateRunning: return fmt.Sprintf("Activity running: %s", placeholder) case obrimProgressStateCompleted: return fmt.Sprintf("Activity completed: %s", placeholder) case obrimProgressStateCanceled: return fmt.Sprintf("Activity canceled: %s", placeholder) } } return "" } // obrimProgressGenerateVisual generates CLI-friendly visual progress representations. func obrimProgressGenerateVisual( progressType string, percentage int, placeholder string, ) string { switch progressType { case obrimProgressTypeCountable: filled := int( math.Round( (float64(percentage) / 100.0) * obrimProgressVisualWidth, ), ) if filled > obrimProgressVisualWidth { filled = obrimProgressVisualWidth } if filled < 0 { filled = 0 } return fmt.Sprintf( "[%s%s] %d%%", strings.Repeat("=", filled), strings.Repeat(" ", obrimProgressVisualWidth-filled), percentage, ) case obrimProgressTypeUncountable: return fmt.Sprintf("[...] %s", placeholder) } return "" } // obrimProgressBuildResponse constructs standardized utility response payloads. func obrimProgressBuildResponse( status bool, code string, payload interface{}, ) ObrimProgressResponse { if !status { payload = nil } return ObrimProgressResponse{ Status: status, Code: code, Payload: payload, } }