package com.atlassian.bitbucket.mesh.request;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Optional;

public interface RequestManager {

    /**
     * @return the current {@link RequestContext}, or {@link Optional#empty empty} if there isn't one
     */
    @Nonnull
    Optional<RequestContext> getContext();

    /**
     * @return the current {@link RequestContext}
     * @throws IllegalStateException if there is no current request
     */
    @Nonnull
    RequestContext getContextOrThrow();

    /**
     * Sets up and tears down a {@link RequestContext} that can be used to access metadata about the current
     * request.
     *
     * @param descriptor describes the current request, providing a common view of requests potentially made
     *                   using different protocols
     * @param callback   called with the newly created {@link RequestContext}
     * @param <T>        type of the callback return value
     * @return the return value of the callback
     */
    @Nullable
    <T> T withContext(@Nonnull RequestDescriptor descriptor, @Nonnull RequestCallback<T> callback);
}
