/*
 * 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.knox.gateway.dispatch;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIBuilder;

class NiFiResponseUtil {

  static void modifyOutboundResponse(HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
    // Only want to rewrite the Location header on a HTTP 302
    if (inboundResponse.getStatusLine().getStatusCode() == HttpServletResponse.SC_FOUND) {
      Header originalLocationHeader = inboundResponse.getFirstHeader("Location");
      if (originalLocationHeader != null) {
        String originalLocation = originalLocationHeader.getValue();
        URIBuilder originalLocationUriBuilder;
        try {
          originalLocationUriBuilder = new URIBuilder(originalLocation);
        } catch (URISyntaxException e) {
          throw new RuntimeException("Unable to parse URI from Location header", e);
        }
        URIBuilder inboundRequestUriBuilder;
        try {
          inboundRequestUriBuilder = new URIBuilder(inboundRequest.getRequestURI());
        } catch (URISyntaxException e) {
          throw new RuntimeException("Unable to parse the inbound request URI", e);
        }
        /*
         * if the path specified in the Location header fron the inbound response contains the inbound request's URI's path,
         * then it's going to the same web context, and the Location header should be updated based on the X_FORWARDED_* headers.
         */
        String inboundRequestUriPath = inboundRequestUriBuilder.getPath();
        String originalLocationUriPath = originalLocationUriBuilder.getPath();
        if (originalLocationUriPath.contains(inboundRequestUriPath)) {
          // check for trailing slash of Location header if it exists and preserve it
          final String trailingSlash = originalLocationUriPath.endsWith("/") ? "/" : "";
          // retain query params
          final List<NameValuePair> queryParams = originalLocationUriBuilder.getQueryParams();

          // check for proxy settings
          final String scheme = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PROTO);
          final String host = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_HOST);
          final String port = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PORT);

          final String baseContextPath = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_CONTEXT);
          final String pathInfo = inboundRequest.getPathInfo();

          try {
            final URI newLocation = new URIBuilder().setScheme(scheme).setHost(host).setPort((StringUtils.isNumeric(port) ? Integer.parseInt(port) : -1)).setPath(
                baseContextPath + pathInfo + trailingSlash).setParameters(queryParams).build();
            outboundResponse.setHeader("Location", newLocation.toString());
          } catch (URISyntaxException e) {
            throw new RuntimeException("Unable to rewrite Location header in response", e);
          }
        }
      } else {
        throw new RuntimeException("Received HTTP 302, but response is missing Location header");
      }
    }
  }
}

