package com.atlassian.bitbucket.mesh.throttle;

import javax.annotation.Nonnull;
import java.util.OptionalInt;

/**
 * Indicates the {@link AdaptiveResourceThrottleStrategy adaptive throttling strategy} is unavailable for the
 * configured resource. The {@link #reason} broadly indicates {@link Reason why} this was unavailable.
 * The optional {@link #fallbackFixedTickets} allows the throwing code to suggest the fixed ticket limit to use.
 */
public class AdaptiveThrottlingUnavailableException extends RuntimeException {

    private final Integer fallbackFixedTickets;
    private final Reason reason;

    public AdaptiveThrottlingUnavailableException(@Nonnull Reason reason) {
        this.fallbackFixedTickets = null;
        this.reason = reason;
    }

    public AdaptiveThrottlingUnavailableException(int fallbackFixedTickets, @Nonnull Reason reason) {
        this.fallbackFixedTickets = fallbackFixedTickets;
        this.reason = reason;
    }

    @Nonnull
    public Reason getReason() {
        return reason;
    }

    @Nonnull
    public OptionalInt getFixedTickets() {
        return fallbackFixedTickets == null ? OptionalInt.empty() : OptionalInt.of(fallbackFixedTickets);
    }

    public enum Reason {

        ERROR_RUNTIME("error-runtime"),
        ERROR_CONFIGURATION("error-configuration"),
        MEMORY_INSUFFICIENT("memory-insufficient"),
        MEMORY_UNAVAILABLE("memory-unavailable");

        private final String id;

        Reason(String id) {
            this.id = id;
        }

        @Override
        public String toString() {
            return id;
        }
    }
}
