001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.http.client.result;
017
018import java.util.Set;
019
020import static de.cuioss.tools.collect.CollectionLiterals.immutableSet;
021
022/**
023 * HTTP-specific result states that extend the basic CUI result pattern with semantics
024 * tailored for HTTP operations, particularly ETag-aware caching and retry scenarios.
025 *
026 * <h2>State Overview</h2>
027 * <ul>
028 *   <li>{@link #FRESH} - Successfully loaded new content from server</li>
029 *   <li>{@link #CACHED} - Using cached content (ETag indicates not modified)</li>
030 *   <li>{@link #STALE} - Using cached content but it may be outdated</li>
031 *   <li>{@link #RECOVERED} - Succeeded after retry attempts</li>
032 *   <li>{@link #ERROR} - All attempts failed, using fallback if available</li>
033 * </ul>
034 *
035 * <h2>Usage Patterns</h2>
036 *
037 * <h3>1. ETag-Aware Caching</h3>
038 * <pre>
039 * HttpResultObject&lt;String&gt; result = etagHandler.load();
040 * if (result.isFresh()) {
041 *     // New content loaded, update cache
042 *     updateCache(result.getResult(), result.getETag());
043 * } else if (result.isCached()) {
044 *     // Content unchanged, use existing cache
045 *     useExistingContent(result.getResult());
046 * }
047 * </pre>
048 *
049 * <h3>2. Retry Flow Control</h3>
050 * <pre>
051 * if (result.isRecovered()) {
052 *     // Succeeded after retries, log for monitoring
053 *     logger.info("HTTP operation recovered after {} attempts",
054 *         result.getRetryMetrics().getTotalAttempts());
055 * } else if (result.getState() == ERROR) {
056 *     // All retries failed, handle gracefully
057 *     handleFailureWithFallback(result);
058 * }
059 * </pre>
060 *
061 * <h2>State Semantics</h2>
062 * <ul>
063 *   <li><strong>FRESH</strong>: Content was loaded from server, ETag updated</li>
064 *   <li><strong>CACHED</strong>: Server returned 304 Not Modified, content unchanged</li>
065 *   <li><strong>STALE</strong>: Using cached content due to error, may be outdated</li>
066 *   <li><strong>RECOVERED</strong>: Succeeded after 1+ retry attempts</li>
067 *   <li><strong>ERROR</strong>: All retry attempts failed, using default/fallback result</li>
068 * </ul>
069 *
070 * @author Implementation based on CUI result pattern
071 * @see HttpResultObject
072 * @see de.cuioss.uimodel.result.ResultState
073 * @since 1.0
074 */
075public enum HttpResultState {
076
077    /**
078     * Successfully loaded fresh content from the server.
079     * This indicates the content is new or has been updated since the last request.
080     * ETag has been updated to reflect the current content version.
081     */
082    FRESH,
083
084    /**
085     * Using cached content because server indicated it hasn't changed.
086     * This is the optimal case for ETag-aware operations where the server
087     * returned HTTP 304 Not Modified, confirming cached content is current.
088     */
089    CACHED,
090
091    /**
092     * Using cached/fallback content because fresh content couldn't be retrieved.
093     * The cached content may be outdated but provides graceful degradation.
094     * This state indicates potential service degradation that should be monitored.
095     */
096    STALE,
097
098    /**
099     * Operation succeeded but only after retry attempts.
100     * This indicates temporary network/server issues that were successfully overcome.
101     * Retry metrics should be available for observability.
102     */
103    RECOVERED,
104
105    /**
106     * All retry attempts failed.
107     * A default or cached result may be available for graceful degradation,
108     * but the primary operation could not be completed successfully.
109     */
110    ERROR;
111
112    /**
113     * States that indicate successful content retrieval from cache.
114     * These states mean the result can be used reliably for business logic.
115     */
116    public static final Set<HttpResultState> CACHE_STATES = immutableSet(CACHED, STALE);
117
118    /**
119     * States that indicate successful operation completion.
120     * Content is available and can be used, though STALE and RECOVERED
121     * may warrant logging for monitoring purposes.
122     */
123    public static final Set<HttpResultState> SUCCESS_STATES = immutableSet(FRESH, CACHED, RECOVERED);
124
125    /**
126     * States that indicate content freshness concerns.
127     * These states suggest monitoring or validation may be appropriate.
128     */
129    public static final Set<HttpResultState> DEGRADED_STATES = immutableSet(STALE, RECOVERED);
130
131    /**
132     * States that must be handled before accessing the result.
133     * Overrides the base ResultState behavior to include STALE state
134     * as it may require special handling in some contexts.
135     */
136    public static final Set<HttpResultState> MUST_BE_HANDLED = immutableSet(ERROR, STALE);
137}