//
//  ========================================================================
//  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.client;

import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;

import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.util.AttributesMap;

public class HttpConversation extends AttributesMap
{
    private final Deque<HttpExchange> exchanges = new ConcurrentLinkedDeque<>();
    private volatile List<Response.ResponseListener> listeners;

    public Deque<HttpExchange> getExchanges()
    {
        return exchanges;
    }

    /**
     * Returns the list of response listeners that needs to be notified of response events.
     * This list changes as the conversation proceeds, as follows:
     * <ol>
     * <li>
     *     request R1 send => conversation.updateResponseListeners(null)
     *     <ul>
     *         <li>exchanges in conversation: E1</li>
     *         <li>listeners to be notified: E1.listeners</li>
     *     </ul>
     * </li>
     * <li>
     *     response R1 arrived, 401 => conversation.updateResponseListeners(AuthenticationProtocolHandler.listener)
     *     <ul>
     *         <li>exchanges in conversation: E1</li>
     *         <li>listeners to be notified: AuthenticationProtocolHandler.listener</li>
     *     </ul>
     * </li>
     * <li>
     *     request R2 send => conversation.updateResponseListeners(null)
     *     <ul>
     *         <li>exchanges in conversation: E1 + E2</li>
     *         <li>listeners to be notified: E2.listeners + E1.listeners</li>
     *     </ul>
     * </li>
     * <li>
     *     response R2 arrived, 302 => conversation.updateResponseListeners(RedirectProtocolHandler.listener)
     *     <ul>
     *         <li>exchanges in conversation: E1 + E2</li>
     *         <li>listeners to be notified: E2.listeners + RedirectProtocolHandler.listener</li>
     *     </ul>
     * </li>
     * <li>
     *     request R3 send => conversation.updateResponseListeners(null)
     *     <ul>
     *         <li>exchanges in conversation: E1 + E2 + E3</li>
     *         <li>listeners to be notified: E3.listeners + E1.listeners</li>
     *     </ul>
     * </li>
     * <li>
     *     response R3 arrived, 200 => conversation.updateResponseListeners(null)
     *     <ul>
     *         <li>exchanges in conversation: E1 + E2 + E3</li>
     *         <li>listeners to be notified: E3.listeners + E1.listeners</li>
     *     </ul>
     * </li>
     * </ol>
     * Basically the override conversation listener replaces the first exchange response listener,
     * and we also notify the last exchange response listeners (if it's not also the first).
     *
     * This scheme allows for protocol handlers to not worry about other protocol handlers, or to worry
     * too much about notifying the first exchange response listeners, but still allowing a protocol
     * handler to perform completion activities while another protocol handler performs new ones (as an
     * example, the {@link AuthenticationProtocolHandler} stores the successful authentication credentials
     * while the {@link RedirectProtocolHandler} performs a redirect).
     *
     * @return the list of response listeners that needs to be notified of response events
     */
    public List<Response.ResponseListener> getResponseListeners()
    {
        return listeners;
    }

    /**
     * Requests to update the response listener, eventually using the given override response listener,
     * that must be notified instead of the first exchange response listeners.
     * This works in conjunction with {@link #getResponseListeners()}, returning the appropriate response
     * listeners that needs to be notified of response events.
     *
     * @param overrideListener the override response listener
     */
    public void updateResponseListeners(Response.ResponseListener overrideListener)
    {
        // Create a new instance to avoid that iterating over the listeners
        // will notify a listener that may send a new request and trigger
        // another call to this method which will build different listeners
        // which may be iterated over when the iteration continues.
        List<Response.ResponseListener> listeners = new ArrayList<>();
        HttpExchange firstExchange = exchanges.peekFirst();
        HttpExchange lastExchange = exchanges.peekLast();
        if (firstExchange == lastExchange)
        {
            if (overrideListener != null)
                listeners.add(overrideListener);
            else
                listeners.addAll(firstExchange.getResponseListeners());
        }
        else
        {
            // Order is important, we want to notify the last exchange first
            listeners.addAll(lastExchange.getResponseListeners());
            if (overrideListener != null)
                listeners.add(overrideListener);
            else
                listeners.addAll(firstExchange.getResponseListeners());
        }
        this.listeners = listeners;
    }

    public boolean abort(Throwable cause)
    {
        HttpExchange exchange = exchanges.peekLast();
        return exchange != null && exchange.abort(cause);
    }

    @Override
    public String toString()
    {
        return String.format("%s[%x]", HttpConversation.class.getSimpleName(), hashCode());
    }
}
