//
//  ========================================================================
//  Copyright (c) 1995-2015 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.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.client.util.BufferingResponseListener;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/**
 * Utility class that handles HTTP redirects.
 * <p>
 * Applications can disable redirection via {@link Request#followRedirects(boolean)}
 * and then rely on this class to perform the redirect in a simpler way, for example:
 * <pre>
 * HttpRedirector redirector = new HttpRedirector(httpClient);
 *
 * Request request = httpClient.newRequest("http://host/path").followRedirects(false);
 * ContentResponse response = request.send();
 * while (redirector.isRedirect(response))
 * {
 *     // Validate the redirect URI
 *     if (!validate(redirector.extractRedirectURI(response)))
 *         break;
 *
 *     Result result = redirector.redirect(request, response);
 *     request = result.getRequest();
 *     response = result.getResponse();
 * }
 * </pre>
 */
public class HttpRedirector
{
    private static final Logger LOG = Log.getLogger(HttpRedirector.class);
    private static final String SCHEME_REGEXP = "(^https?)";
    private static final String AUTHORITY_REGEXP = "([^/\\?#]+)";
    // The location may be relative so the scheme://authority part may be missing
    private static final String DESTINATION_REGEXP = "(" + SCHEME_REGEXP + "://" + AUTHORITY_REGEXP + ")?";
    private static final String PATH_REGEXP = "([^\\?#]*)";
    private static final String QUERY_REGEXP = "([^#]*)";
    private static final String FRAGMENT_REGEXP = "(.*)";
    private static final Pattern URI_PATTERN = Pattern.compile(DESTINATION_REGEXP + PATH_REGEXP + QUERY_REGEXP + FRAGMENT_REGEXP);
    private static final String ATTRIBUTE = HttpRedirector.class.getName() + ".redirects";

    private final HttpClient client;
    private final ResponseNotifier notifier;

    public HttpRedirector(HttpClient client)
    {
        this.client = client;
        this.notifier = new ResponseNotifier();
    }

    /**
     * @param response the response to check for redirects
     * @return whether the response code is a HTTP redirect code
     */
    public boolean isRedirect(Response response)
    {
        switch (response.getStatus())
        {
            case 301:
            case 302:
            case 303:
            case 307:
            case 308:
                return true;
            default:
                return false;
        }
    }

    /**
     * Redirects the given {@code response}, blocking until the redirect is complete.
     *
     * @param request the original request that triggered the redirect
     * @param response the response to the original request
     * @return a {@link Result} object containing the request to the redirected location and its response
     * @throws InterruptedException if the thread is interrupted while waiting for the redirect to complete
     * @throws ExecutionException if the redirect failed
     * @see #redirect(Request, Response, Response.CompleteListener)
     */
    public Result redirect(Request request, Response response) throws InterruptedException, ExecutionException
    {
        final AtomicReference<Result> resultRef = new AtomicReference<>();
        final CountDownLatch latch = new CountDownLatch(1);
        Request redirect = redirect(request, response, new BufferingResponseListener()
        {
            @Override
            public void onComplete(Result result)
            {
                resultRef.set(new Result(result.getRequest(),
                        result.getRequestFailure(),
                        new HttpContentResponse(result.getResponse(), getContent(), getMediaType(), getEncoding()),
                        result.getResponseFailure()));
                latch.countDown();
            }
        });

        try
        {
            latch.await();
            Result result = resultRef.get();
            if (result.isFailed())
                throw new ExecutionException(result.getFailure());
            return result;
        }
        catch (InterruptedException x)
        {
            // If the application interrupts, we need to abort the redirect
            redirect.abort(x);
            throw x;
        }
    }

    /**
     * Redirects the given {@code response} asynchronously.
     *
     * @param request the original request that triggered the redirect
     * @param response the response to the original request
     * @param listener the listener that receives response events
     * @return the request to the redirected location
     */
    public Request redirect(Request request, Response response, Response.CompleteListener listener)
    {
        if (isRedirect(response))
        {
            String location = response.getHeaders().get("Location");
            URI newURI = extractRedirectURI(response);
            if (newURI != null)
            {
                if (LOG.isDebugEnabled())
                    LOG.debug("Redirecting to {} (Location: {})", newURI, location);
                return redirect(request, response, listener, newURI);
            }
            else
            {
                fail(request, response, new HttpResponseException("Invalid 'Location' header: " + location, response));
                return null;
            }
        }
        else
        {
            fail(request, response, new HttpResponseException("Cannot redirect: " + response, response));
            return null;
        }
    }

    /**
     * Extracts and sanitizes (by making it absolute and escaping paths and query parameters)
     * the redirect URI of the given {@code response}.
     *
     * @param response the response to extract the redirect URI from
     * @return the absolute redirect URI, or null if the response does not contain a valid redirect location
     */
    public URI extractRedirectURI(Response response)
    {
        String location = response.getHeaders().get("location");
        if (location != null)
            return sanitize(location);
        return null;
    }

    private URI sanitize(String location)
    {
        // Redirects should be valid, absolute, URIs, with properly escaped paths and encoded
        // query parameters. However, shit happens, and here we try our best to recover.

        try
        {
            // Direct hit first: if passes, we're good
            return new URI(location);
        }
        catch (URISyntaxException x)
        {
            Matcher matcher = URI_PATTERN.matcher(location);
            if (matcher.matches())
            {
                String scheme = matcher.group(2);
                String authority = matcher.group(3);
                String path = matcher.group(4);
                String query = matcher.group(5);
                if (query.length() == 0)
                    query = null;
                String fragment = matcher.group(6);
                if (fragment.length() == 0)
                    fragment = null;
                try
                {
                    return new URI(scheme, authority, path, query, fragment);
                }
                catch (URISyntaxException xx)
                {
                    // Give up
                }
            }
            return null;
        }
    }

    private Request redirect(Request request, Response response, Response.CompleteListener listener, URI newURI)
    {
        if (!newURI.isAbsolute())
            newURI = request.getURI().resolve(newURI);

        int status = response.getStatus();
        switch (status)
        {
            case 301:
            {
                String method = request.getMethod();
                if (HttpMethod.GET.is(method) || HttpMethod.HEAD.is(method) || HttpMethod.PUT.is(method))
                    return redirect(request, response, listener, newURI, method);
                else if (HttpMethod.POST.is(method))
                    return redirect(request, response, listener, newURI, HttpMethod.GET.asString());
                fail(request, response, new HttpResponseException("HTTP protocol violation: received 301 for non GET/HEAD/POST/PUT request", response));
                return null;
            }
            case 302:
            {
                String method = request.getMethod();
                if (HttpMethod.HEAD.is(method) || HttpMethod.PUT.is(method))
                    return redirect(request, response, listener, newURI, method);
                else
                    return redirect(request, response, listener, newURI, HttpMethod.GET.asString());
            }
            case 303:
            {
                String method = request.getMethod();
                if (HttpMethod.HEAD.is(method))
                    return redirect(request, response, listener, newURI, method);
                else
                    return redirect(request, response, listener, newURI, HttpMethod.GET.asString());
            }
            case 307:
            case 308:
            {
                // Keep same method
                return redirect(request, response, listener, newURI, request.getMethod());
            }
            default:
            {
                fail(request, response, new HttpResponseException("Unhandled HTTP status code " + status, response));
                return null;
            }
        }
    }

    private Request redirect(Request request, Response response, Response.CompleteListener listener, URI location, String method)
    {
        HttpRequest httpRequest = (HttpRequest)request;
        HttpConversation conversation = httpRequest.getConversation();
        Integer redirects = (Integer)conversation.getAttribute(ATTRIBUTE);
        if (redirects == null)
            redirects = 0;
        if (redirects < client.getMaxRedirects())
        {
            ++redirects;
            conversation.setAttribute(ATTRIBUTE, redirects);
            return sendRedirect(httpRequest, response, listener, location, method);
        }
        else
        {
            fail(request, response, new HttpResponseException("Max redirects exceeded " + redirects, response));
            return null;
        }
    }

    private Request sendRedirect(final HttpRequest httpRequest, Response response, Response.CompleteListener listener, URI location, String method)
    {
        try
        {
            Request redirect = client.copyRequest(httpRequest, location);

            // Use given method
            redirect.method(method);

            redirect.onRequestBegin(new Request.BeginListener()
            {
                @Override
                public void onBegin(Request redirect)
                {
                    Throwable cause = httpRequest.getAbortCause();
                    if (cause != null)
                        redirect.abort(cause);
                }
            });

            redirect.send(listener);
            return redirect;
        }
        catch (Throwable x)
        {
            fail(httpRequest, response, x);
            return null;
        }
    }

    protected void fail(Request request, Response response, Throwable failure)
    {
        HttpConversation conversation = ((HttpRequest)request).getConversation();
        conversation.updateResponseListeners(null);
        List<Response.ResponseListener> listeners = conversation.getResponseListeners();
        notifier.notifyFailure(listeners, response, failure);
        notifier.notifyComplete(listeners, new Result(request, response, failure));
    }
}
