001package io.jstach.rainbowgum;
002
003import java.lang.System.Logger.Level;
004import java.util.Objects;
005import java.util.concurrent.ExecutionException;
006
007/**
008 * A container for the response of some sort of request or action. Logging is usually with
009 * out a return value but there are certain scenarios where a return value is needed
010 * particularly when doing health checks.
011 *
012 * @apiNote At the moment this class is largely an internal detail as extension points do
013 * not create responses however {@link #status()} objects are created by extension points.
014 * @see Status
015 */
016public sealed interface LogResponse {
017
018        /**
019         * Configuration name of the component.
020         * @return name.
021         */
022        public String name();
023
024        /**
025         * Status of the response.
026         * @return status.
027         */
028        public Status status();
029
030        /**
031         * Component type.
032         * @return interface class.
033         */
034        public Class<?> type();
035
036        /**
037         * Log component status check.
038         */
039        sealed interface Status {
040
041                /**
042                 * Level is used here to indicate the severity of the status.
043                 * @return level.
044                 */
045                public System.Logger.Level level();
046
047                /**
048                 * Standard status.
049                 */
050                public enum StandardStatus implements Status {
051
052                        /**
053                         * Nothing to report.
054                         */
055                        IGNORED() {
056                                @Override
057                                public Level level() {
058                                        return Level.DEBUG;
059                                }
060                        },
061                        /**
062                         * OK.
063                         */
064                        OK() {
065                                @Override
066                                public Level level() {
067                                        return Level.INFO;
068                                }
069                        }
070
071                }
072
073                /**
074                 * Creates an error status of a throwable.
075                 * @param e throwable.
076                 * @return error status.
077                 */
078                static ErrorStatus ofError(Throwable e) {
079                        return ErrorStatus.of(e);
080                }
081
082                /**
083                 * Error status.
084                 *
085                 * @param message error message.
086                 */
087                record ErrorStatus(String message) implements Status {
088
089                        @Override
090                        public Level level() {
091                                return Level.ERROR;
092                        }
093
094                        static ErrorStatus of(ExecutionException e) {
095                                var cause = e.getCause();
096                                if (cause == null)
097                                        cause = e;
098                                return of(cause);
099                        }
100
101                        static ErrorStatus of(Throwable e) {
102                                String message = Objects.requireNonNullElse(e.getMessage(), "unknown error");
103                                return new Status.ErrorStatus(message);
104                        }
105                }
106
107        }
108
109}
110
111/**
112 * A marker interface for pluggable components in the logging system.
113 *
114 * @apiNote this interface is an internal detail.
115 */
116interface LogComponent {
117
118}
119
120record Response(Class<? extends LogComponent> type, String name, LogResponse.Status status) implements LogResponse {
121
122}