//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.continuation;

import javax.servlet.ServletResponse;

/* ------------------------------------------------------------ */
/**
 * Continuation.
 * 
 * A continuation is a mechanism by which a HTTP Request can be suspended and
 * restarted after a timeout or an asynchronous event has occurred.
 * <p>
 * The continuation mechanism is a portable mechanism that will work 
 * asynchronously without additional configuration of all jetty-7, 
 * jetty-8 and Servlet 3.0 containers.   With the addition of 
 * the {@link ContinuationFilter}, the mechanism will also work
 * asynchronously on jetty-6 and non-asynchronously on any 
 * servlet 2.5 container.
 * <p>
 * The Continuation API is a simplification of the richer async API
 * provided by the servlet-3.0 and an enhancement of the continuation
 * API that was introduced with jetty-6. 
 * </p>
 * <h1>Continuation Usage</h1>
 * <p>
 * A continuation object is obtained for a request by calling the 
 * factory method {@link ContinuationSupport#getContinuation(ServletRequest)}.
 * The continuation type returned will depend on the servlet container
 * being used.
 * </p> 
 * <p>
 * There are two distinct style of operation of the continuation API.
 * </p>
 * <h3>Suspend/Resume Usage</h3> 
 * <p>The suspend/resume style is used when a servlet and/or
 * filter is used to generate the response after a asynchronous wait that is
 * terminated by an asynchronous handler.
 * </p>
 * <pre>
 * <b>Filter/Servlet:</b>
 *   // if we need to get asynchronous results
 *   Object results = request.getAttribute("results);
 *   if (results==null)
 *   {
 *     Continuation continuation = ContinuationSupport.getContinuation(request);
 *     continuation.suspend();
 *     myAsyncHandler.register(continuation);
 *     return; // or continuation.undispatch();
 *   }
 * 
 * async wait ...
 * 
 * <b>Async Handler:</b>
 *   // when the waited for event happens
 *   continuation.setAttribute("results",event);
 *   continuation.resume();
 *   
 * <b>Filter/Servlet:</b>
 *   // when the request is redispatched 
 *   if (results==null)
 *   {
 *     ... // see above
 *   }
 *   else
 *   {
 *     response.getOutputStream().write(process(results));
 *   }
 * </pre> 
 * <h3>Suspend/Complete Usage</h3> 
 * <p>
 * The suspend/complete style is used when an asynchronous handler is used to 
 * generate the response:
 * </p>
 * <pre>
 * <b>Filter/Servlet:</b>
 *   // when we want to enter asynchronous mode
 *   Continuation continuation = ContinuationSupport.getContinuation(request);
 *   continuation.suspend(response); // response may be wrapped
 *   myAsyncHandler.register(continuation);
 *   return; // or continuation.undispatch();
 *
 * <b>Wrapping Filter:</b>
 *   // any filter that had wrapped the response should be implemented like:
 *   try
 *   {
 *     chain.doFilter(request,wrappedResponse);
 *   }
 *   finally
 *   {
 *     if (!continuation.isResponseWrapped())
 *       wrappedResponse.finish()
 *     else
 *       continuation.addContinuationListener(myCompleteListener)
 *   }
 *
 * async wait ...
 *
 * <b>Async Handler:</b>
 *   // when the async event happens
 *   continuation.getServletResponse().getOutputStream().write(process(event));
 *   continuation.complete()
 * </pre>
 * 
 * <h1>Continuation Timeout</h1>
 * <p>
 * If a continuation is suspended, but neither {@link #complete()} or {@link #resume()} is
 * called during the period set by {@link #setTimeout(long)}, then the continuation will
 * expire and {@link #isExpired()} will return true. 
 * </p>
 * <p>
 * When a continuation expires, the {@link ContinuationListener#onTimeout(Continuation)}
 * method is called on any {@link ContinuationListener} that has been registered via the
 * {@link #addContinuationListener(ContinuationListener)} method. The onTimeout handlers 
 * may write a response and call {@link #complete()}. If {@link #complete()} is not called, 
 * then the container will redispatch the request as if {@link #resume()} had been called,
 * except that {@link #isExpired()} will be true and {@link #isResumed()} will be false.
 * </p>
 * 
 * @see ContinuationSupport
 * @see ContinuationListener
 * 
 */
public interface Continuation
{
    public final static String ATTRIBUTE = "org.eclipse.jetty.continuation";

    /* ------------------------------------------------------------ */
    /**
     * Set the continuation timeout.
     * 
     * @param timeoutMs
     *            The time in milliseconds to wait before expiring this
     *            continuation after a call to {@link #suspend()} or {@link #suspend(ServletResponse)}.
     *            A timeout of <=0 means the continuation will never expire.
     */
    void setTimeout(long timeoutMs);

    /* ------------------------------------------------------------ */
    /**
     * Suspend the processing of the request and associated
     * {@link ServletResponse}.
     * 
     * <p>
     * After this method has been called, the lifecycle of the request will be
     * extended beyond the return to the container from the
     * {@link Servlet#service(ServletRequest, ServletResponse)} method and
     * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
     * calls. When a suspended request is returned to the container after
     * a dispatch, then the container will not commit the associated response
     * (unless an exception other than {@link ContinuationThrowable} is thrown).
     * </p>
     * 
     * <p>
     * When the thread calling the filter chain and/or servlet has returned to
     * the container with a suspended request, the thread is freed for other
     * tasks and the request is held until either:
     * <ul>
     * <li>a call to {@link #resume()}.</li>
     * <li>a call to {@link #complete()}.</li>
     * <li>the timeout expires.</li>
     * </ul>
     * <p>
     * Typically suspend with no arguments is uses when a call to {@link #resume()}
     * is expected. If a call to {@link #complete()} is expected, then the 
     * {@link #suspend(ServletResponse)} method should be used instead of this method.
     * </p>
     * 
     * @exception IllegalStateException
     *                If the request cannot be suspended
     */
    void suspend();
    
    
    /* ------------------------------------------------------------ */
    /**
     * Suspend the processing of the request and associated
     * {@link ServletResponse}.
     * 
     * <p>
     * After this method has been called, the lifecycle of the request will be
     * extended beyond the return to the container from the
     * {@link Servlet#service(ServletRequest, ServletResponse)} method and
     * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
     * calls. When a suspended request is returned to the container after
     * a dispatch, then the container will not commit the associated response
     * (unless an exception other than {@link ContinuationThrowable} is thrown).
     * </p>
     * <p>
     * When the thread calling the filter chain and/or servlet has returned to
     * the container with a suspended request, the thread is freed for other
     * tasks and the request is held until either:
     * <ul>
     * <li>a call to {@link #resume()}.</li>
     * <li>a call to {@link #complete()}.</li>
     * <li>the timeout expires.</li>
     * </ul>
     * <p>
     * Typically suspend with a response argument is uses when a call to {@link #complete()}
     * is expected. If a call to {@link #resume()} is expected, then the 
     * {@link #suspend()} method should be used instead of this method.
     * </p>
     * <p>
     * Filters that may wrap the response object should check {@link #isResponseWrapped()}
     * to decide if they should destroy/finish the wrapper. If {@link #isResponseWrapped()}
     * returns true, then the wrapped request has been passed to the asynchronous
     * handler and the wrapper should not be destroyed/finished until after a call to 
     * {@link #complete()} (potentially using a {@link ContinuationListener#onComplete(Continuation)}
     * listener).
     * 
     * @param response The response to return via a call to {@link #getServletResponse()}
     * @exception IllegalStateException
     *                If the request cannot be suspended
     */
    void suspend(ServletResponse response);

    /* ------------------------------------------------------------ */
    /**
     * Resume a suspended request.
     * 
     * <p>
     * This method can be called by any thread that has been passed a reference
     * to a continuation. When called the request is redispatched to the
     * normal filter chain and servlet processing with {@link #isInitial()} false.
     * </p>
     * <p>
     * If resume is called before a suspended request is returned to the
     * container (ie the thread that called {@link #suspend()} is still
     * within the filter chain and/or servlet service method), then the resume
     * does not take effect until the call to the filter chain and/or servlet
     * returns to the container. In this case both {@link #isSuspended()} and
     * {@link #isResumed()} return true. Multiple calls to resume are ignored.
     * </p>
     * <p>
     * Typically resume() is used after a call to {@link #suspend()} with
     * no arguments. The dispatch after a resume call will use the original
     * request and response objects, even if {@link #suspend(ServletResponse)} 
     * had been passed a wrapped response.
     * </p>
     * 
     * @see #suspend()
     * @exception IllegalStateException if the request is not suspended.
     * 
     */
    void resume();

    /* ------------------------------------------------------------ */
    /**
     * Complete a suspended request.
     * 
     * <p>
     * This method can be called by any thread that has been passed a reference
     * to a suspended request. When a request is completed, the associated
     * response object committed and flushed. The request is not redispatched.
     * </p>
     * 
     * <p>
     * If complete is called before a suspended request is returned to the
     * container (ie the thread that called {@link #suspend()} is still
     * within the filter chain and/or servlet service method), then the complete
     * does not take effect until the call to the filter chain and/or servlet
     * returns to the container. In this case both {@link #isSuspended()} and
     * {@link #isResumed()} return true.
     * </p>
     * 
     * <p>
     * Typically resume() is used after a call to {@link #suspend(ServletResponse)} with
     * a possibly wrapped response. The async handler should use the response
     * provided by {@link #getServletResponse()} to write the response before
     * calling {@link #complete()}. If the request was suspended with a 
     * call to {@link #suspend()} then no response object will be available via
     * {@link #getServletResponse()}.
     * </p>
     * 
     * <p>
     * Once complete has been called and any thread calling the filter chain
     * and/or servlet chain has returned to the container, the request lifecycle
     * is complete. The container is able to recycle request objects, so it is
     * not valid hold a request or continuation reference after the end of the 
     * life cycle.
     * 
     * @see #suspend()
     * @exception IllegalStateException
     *                if the request is not suspended.
     * 
     */
    void complete();

    /* ------------------------------------------------------------ */
    /**
     * @return true after {@link #suspend()} has been called and before the
     *         request has been redispatched due to being resumed, completed or
     *         timed out.
     */
    boolean isSuspended();

    /* ------------------------------------------------------------ */
    /**
     * @return true if the request has been redispatched by a call to
     *         {@link #resume()}. Returns false after any subsequent call to
     *         suspend
     */
    boolean isResumed();

    /* ------------------------------------------------------------ */
    /**
     * @return true after a request has been redispatched as the result of a
     *         timeout. Returns false after any subsequent call to suspend.
     */
    boolean isExpired();

    /* ------------------------------------------------------------ */
    /**
     * @return true while the request is within the initial dispatch to the
     *         filter chain and/or servlet. Will return false once the calling
     *         thread has returned to the container after suspend has been
     *         called and during any subsequent redispatch.
     */
    boolean isInitial();

    /* ------------------------------------------------------------ */
    /**
     * Is the suspended response wrapped.
     * <p>
     * Filters that wrap the response object should check this method to 
     * determine if they should destroy/finish the wrapped response. If 
     * the request was suspended with a call to {@link #suspend(ServletResponse)}
     * that passed the wrapped response, then the filter should register
     * a {@link ContinuationListener} to destroy/finish the wrapped response
     * during a call to {@link ContinuationListener#onComplete(Continuation)}.
     * @return True if {@link #suspend(ServletResponse)} has been passed a
     * {@link ServletResponseWrapper} instance.
     */
    boolean isResponseWrapped();


    /* ------------------------------------------------------------ */
    /**
     * Get the suspended response.
     * @return the {@link ServletResponse} passed to {@link #suspend(ServletResponse)}.
     */
    ServletResponse getServletResponse();
    
    /* ------------------------------------------------------------ */
    /** 
     * Add a ContinuationListener.
     * 
     * @param listener
     */
    void addContinuationListener(ContinuationListener listener);
    
    /* ------------------------------------------------------------ */
    /** Set a request attribute.
     * This method is a convenience method to call the {@link ServletRequest#setAttribute(String, Object)}
     * method on the associated request object.
     * This is a thread safe call and may be called by any thread.
     * @param name the attribute name
     * @param attribute the attribute value
     */
    public void setAttribute(String name, Object attribute);
    
    /* ------------------------------------------------------------ */
    /** Get a request attribute.
     * This method is a convenience method to call the {@link ServletRequest#getAttribute(String)}
     * method on the associated request object.
     * This is a thread safe call and may be called by any thread.
     * @param name the attribute name
     * @return the attribute value
     */
    public Object getAttribute(String name);
    
    /* ------------------------------------------------------------ */
    /** Remove a request attribute.
     * This method is a convenience method to call the {@link ServletRequest#removeAttribute(String)}
     * method on the associated request object.
     * This is a thread safe call and may be called by any thread.
     * @param name the attribute name
     */
    public void removeAttribute(String name);
    
    /* ------------------------------------------------------------ */
    /**
     * Undispatch the request.
     * <p>
     * This method can be called on a suspended continuation in order
     * to exit the dispatch to the filter/servlet by throwing a {@link ContinuationThrowable}
     * which is caught either by the container or the {@link ContinuationFilter}.
     * This is an alternative to simply returning from the dispatch in the case
     * where filters in the filter chain may not be prepared to handle a suspended
     * request.
     * </p>
     * This method should only be used as a last resort and a normal return is a prefereable
     * solution if filters can be updated to handle that case.
     * 
     * @throws ContinuationThrowable thrown if the request is suspended. The instance of the 
     * exception may be reused on subsequent calls, so the stack frame may not be accurate.
     */
    public void undispatch() throws ContinuationThrowable;
}
