/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package org.apache.ahc;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeoutException;

import org.apache.ahc.codec.HttpRequestMessage;
import org.apache.ahc.codec.HttpResponseMessage;

/**
 * Future that wraps the response of an asynchronous HTTP request.  It simply
 * extends FutureTask to borrow AQS.  This future transitions to <tt>done</tt> 
 * through setting the result or the exception.  The instances are considered 
 * one time objects; i.e. once completed, the instance may not be reused.
 * <p>
 * Also, cancellation through this future is not supported.
 */
public class ResponseFuture extends FutureTask<HttpResponseMessage> 
        implements Future<HttpResponseMessage> {
    // dummy instance because I use the FutureTask constructor
    // is not really used...
    private static final Callable<HttpResponseMessage> DUMMY = 
            new Callable<HttpResponseMessage>() {
                public HttpResponseMessage call() throws Exception {
                    return null;
                }
    };
    
    private final HttpRequestMessage request;
    private final BlockingQueue<ResponseFuture> queue;
    private final AsyncHttpClientCallback callback;
    
    /**
     * Constructor.  Optionally one can pass in the completion queue and/or the
     * callback object.
     * 
     * @param queue optional completion queue.  If not null, this future will be
     * placed in the queue on completion.
     */
    public ResponseFuture(HttpRequestMessage request, 
            BlockingQueue<ResponseFuture> queue) {
        super(DUMMY);
        this.request = request;
        this.queue = queue;
        this.callback = request.getCallback();
    }
    
    public HttpRequestMessage getRequest() {
        return request;
    }
    
    /**
     * On completion, adds this future object to the completion queue if it is 
     * not null.
     */
    @Override
    protected void done() {
        // add itself to the blocking queue so clients can pick it up
        if (queue != null) {
            queue.add(this);
        }
    }

    /**
     * Sets the response and completes the future.  If a non-null callback was
     * provided, the callback will be invoked 
     * (<tt>AsyncHttpClientCallback.onResponse()</tt>) on the thread on which
     * this method is invoked.
     */
    @Override
    public void set(HttpResponseMessage v) {
        try {
            // fire the callback before completing the future to 
            // ensure everything gets handled before the future gets 
            // completed. 
        if (callback != null) {
            callback.onResponse(v);
        }
        } finally {
            super.set(v);
        }
    }

    /**
     * Sets the exception and completes the future.  If a non-null callback was
     * provided, the callback will be invoked 
     * (<tt>AsyncHttpClientCallback.onException()</tt> or 
     * <tt>AsyncHttpClientCallback.onTimeout()</tt>) on the thread on which
     * this method is invoked.
     */
    @Override
    public void setException(Throwable t) {
        try {
            // fire the callback before completing the future to 
            // ensure everything gets handled before the future gets 
            // completed. 
        if (callback != null) {
            if (t instanceof TimeoutException) {
                callback.onTimeout();
            } else {
                callback.onException(t);
            }
        }
        } finally {
            super.setException(t);
        }
    }
    
    /**
     * Canceling via this method is not allowed.  An 
     * UnsupportedOperationException will be thrown.
     */
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        throw new UnsupportedOperationException("we don't support canceling asynchronous HTTP request via this method...");
    }
}
