package com.atlassian.bitbucket.request;

import com.atlassian.bitbucket.event.request.RequestEndedEvent;
import com.atlassian.bitbucket.event.request.RequestStartedEvent;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * Sets up and tears down all logic for processing requests, such as logging, access logging, profiling and publishing
 * {@link RequestStartedEvent} and
 * {@link RequestEndedEvent}.
 */
public interface RequestManager {
    /**
     * Sets up and tears down all logic for processing requests.
     * @param callback called after the {@link RequestStartedEvent} has been published.
     * @param requestInfoProvider provides request details such as sessionId, remoteAddress that are used to
     *                            set up logging.
     * @return the return value of the callback
     * @throws E when {@link RequestCallback#withRequest(RequestContext)} throws an exception.
     */
    @Nullable
    <T, E extends Exception> T doAsRequest(@Nonnull RequestCallback<T, E> callback,
                                           @Nonnull RequestInfoProvider requestInfoProvider) throws E;

    /**
     * @return the context of the current request. Returns {@code null} if there is no current request, for instance
     *         when running a task in a background thread.
     */
    @Nullable
    RequestContext getRequestContext();

    /**
     * @return the metadata of the current request. Returns {@code null} if there is no current request.
     */
    @Nullable
    RequestMetadata getRequestMetadata();
}
