/*
 * 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.sling.auth.core.spi;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.auth.core.AuthenticationSupport;
import org.apache.sling.auth.core.AuthUtil;
import org.slf4j.LoggerFactory;

public class DefaultAuthenticationFeedbackHandler implements
        AuthenticationFeedbackHandler {

    /**
     * Handles an optional request for a redirect after successful
     * authentication and <code>true</code> if the request has been redirected.
     * <p>
     * This method checks {@link AuthenticationSupport#REDIRECT_PARAMETER}
     * request parameter for the redirect target. This parameter is handled
     * as follows:
     * <ul>
     * <li>If the parameter does not exist, the method does not redirect and
     * <code>false</code> is returned.</li>
     * <li>If the parameter is the string <code>true</code> or is empty, a
     *  redirect response to the request URI (<code>HttpServletRequest.getRequestURI()</code>)
     *  is sent and <code>true</code> is returned.</li>
     * <li>If the parameter is a relative path, the path is made absolute
     *  by resolving it relative to the request URI
     *  (<code>HttpServletRequest.getRequestURI()</code>). The resulting
     *  target is validated with the
     *  {@link AbstractAuthenticationHandler#isRedirectValid(HttpServletRequest, String)}
     *  method. If valid a redirect to that target is sent back and <code>true</code>
     *  is returned. Otherwise a redirect to the servlet context root is
     *  sent back and <code>true</code> is returned.</li>
     * <li>If the parameter is an absolute path it is validated with the
     *  {@link AbstractAuthenticationHandler#isRedirectValid(HttpServletRequest, String)}
     *  method. If valid a redirect to that path is sent back and <code>true</code>
     *  is returned. Otherwise a redirect to the servlet context root is
     *  sent back and <code>true</code> is returned.</li>
     *  </ul>
     * If sending the redirect response fails due to some IO problems, the
     * request is still terminated but an error message is logged indicating the
     * problem.
     *
     * @return <code>true</code> if redirect was requested. Otherwise
     *         <code>false</code> is returned. Note, that <code>true</code> is
     *         returned regardless of whether sending the redirect response
     *         succeeded or not.
     *
     * @since 1.0.4 (bundle version 1.0.8) the target is validated with the
     *        {@link AbstractAuthenticationHandler#isRedirectValid(HttpServletRequest, String)}
     *        method.
     */
    public static boolean handleRedirect(final HttpServletRequest request,
            final HttpServletResponse response) {

        final String redirect = getValidatedRedirectTarget(request);
        if (redirect != null) {
            // and redirect ensuring the response is sent to the client
            try {
                response.sendRedirect(redirect);
            } catch (Exception e) {
                // expected: IOException and IllegalStateException
                LoggerFactory.getLogger(
                    DefaultAuthenticationFeedbackHandler.class).error(
                    "handleRedirect: Failed to send redirect to " + redirect
                        + ", aborting request without redirect", e);
            }

            // consider the request done
            return true;
        }

        // no redirect requested
        return false;
    }

    private static String getValidatedRedirectTarget(
            final HttpServletRequest request) {
        String redirect = request.getParameter(AuthenticationSupport.REDIRECT_PARAMETER);
        if (redirect == null) {
            return null;
        }

        // redirect to the same path
        if ("true".equalsIgnoreCase(redirect) || redirect.length() == 0) {
            return request.getRequestURI();
        }

        // redirect relative to the current request (make absolute)
        if (!redirect.startsWith("/") && !redirect.contains("://")) {
            String path = request.getRequestURI();
            path = path.substring(request.getContextPath().length());
            int lastSlash = path.lastIndexOf('/');
            path = (lastSlash > 0) ? path.substring(0, lastSlash + 1) : path;
            redirect = path.concat(redirect);
            redirect = ResourceUtil.normalize(redirect);
        }

        // prepend context path if necessary
        if (redirect.startsWith("/") && !redirect.startsWith(request.getContextPath())) {
            redirect = request.getContextPath().concat(redirect);
        }

        // absolute target (in the servlet context)
        if (!AuthUtil.isRedirectValid(request, redirect)) {
            LoggerFactory.getLogger(DefaultAuthenticationFeedbackHandler.class).error(
                "handleRedirect: Redirect target '{}' is invalid, redirecting to '/'",
                redirect);
            redirect = "/";
        }

        return redirect;
    }

    /**
     * This default implementation does nothing.
     * <p>
     * Extensions of this class may overwrite to cleanup any internal state.
     */
    public void authenticationFailed(HttpServletRequest request,
            HttpServletResponse response, AuthenticationInfo authInfo) {
    }

    /**
     * This default implementation calls the
     * {@link #handleRedirect(HttpServletRequest, HttpServletResponse)} method
     * to optionally redirect the request after successful authentication.
     * <p>
     * Extensions of this class may overwrite this method to perform additional
     * cleanup etc.
     *
     * @return the result of calling the
     *            {@link #handleRedirect(HttpServletRequest, HttpServletResponse)}
     *            method.
     */
    public boolean authenticationSucceeded(HttpServletRequest request,
            HttpServletResponse response, AuthenticationInfo authInfo) {
        return handleRedirect(request, response);
    }

}
