/**
 * 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.ambari.server.proxy;

import com.google.gson.Gson;
import org.apache.ambari.server.controller.internal.URLStreamProvider;
import org.apache.ambari.server.view.ImpersonatorSettingImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.Map;
import java.util.List;
import java.util.HashMap;

@Path("/")
public class ProxyService {

  public static final int URL_CONNECT_TIMEOUT = 20000;
  public static final int URL_READ_TIMEOUT = 15000;
  public static final int HTTP_ERROR_RANGE_START = Response.Status.BAD_REQUEST.getStatusCode();

  private static final String REQUEST_TYPE_GET = "GET";
  private static final String REQUEST_TYPE_POST = "POST";
  private static final String REQUEST_TYPE_PUT = "PUT";
  private static final String REQUEST_TYPE_DELETE = "DELETE";
  private static final String QUERY_PARAMETER_URL = "url=";
  private static final String AMBARI_PROXY_PREFIX = "AmbariProxy-";
  private static final String ERROR_PROCESSING_URL = "Error occurred during processing URL ";
  private static final String INVALID_PARAM_IN_URL = "Invalid query params found in URL ";

  private final static Logger LOG = LoggerFactory.getLogger(ProxyService.class);

  @GET
  public Response processGetRequestForwarding(@Context HttpHeaders headers, @Context UriInfo ui) {
    return handleRequest(REQUEST_TYPE_GET, ui, null, headers);
  }

  @POST
  @Consumes({MediaType.WILDCARD, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON})
  public Response processPostRequestForwarding(InputStream body, @Context HttpHeaders headers, @Context UriInfo ui) {
    return handleRequest(REQUEST_TYPE_POST, ui, body, headers);
  }

  @PUT
  @Consumes({MediaType.WILDCARD, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON})
  public Response processPutRequestForwarding(InputStream body, @Context HttpHeaders headers, @Context UriInfo ui) {
    return handleRequest(REQUEST_TYPE_PUT, ui, body, headers);
  }

  @DELETE
  public Response processDeleteRequestForwarding(@Context HttpHeaders headers, @Context UriInfo ui) {
    return handleRequest(REQUEST_TYPE_DELETE, ui, null, headers);
  }

  private Response handleRequest(String requestType, UriInfo ui, InputStream body, HttpHeaders headers) {
    URLStreamProvider urlStreamProvider = new URLStreamProvider(URL_CONNECT_TIMEOUT,
                                                URL_READ_TIMEOUT, null, null, null);
    String query = ui.getRequestUri().getQuery();
    if (query != null && query.indexOf(QUERY_PARAMETER_URL) != -1) {
      String url = query.replaceFirst(QUERY_PARAMETER_URL, "");

      MultivaluedMap<String, String> m = ui.getQueryParameters();
      if (m.containsKey(ImpersonatorSettingImpl.DEFAULT_DO_AS_PARAM)) {              // Case doesn't matter
        LOG.error(INVALID_PARAM_IN_URL + url);
        return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).type(MediaType.TEXT_PLAIN).
            entity(INVALID_PARAM_IN_URL).build();
      }
      
      try {
        HttpURLConnection connection = urlStreamProvider.processURL(url, requestType, body, getHeaderParamsToForward(headers));
        int responseCode = connection.getResponseCode();
        InputStream resultInputStream = null;
        if (responseCode >= HTTP_ERROR_RANGE_START) {
          resultInputStream = connection.getErrorStream();
        } else {
          resultInputStream = connection.getInputStream();
        }
        String contentType = connection.getContentType();
        Response.ResponseBuilder rb = Response.status(responseCode);
        if (contentType.indexOf(APPLICATION_JSON) != -1) {
          rb.entity(new Gson().fromJson(new InputStreamReader(resultInputStream), Map.class));
        } else {
          rb.entity(resultInputStream);
        }
        return rb.type(contentType).build();
      } catch (IOException e) {
        LOG.error(ERROR_PROCESSING_URL + url, e);
        return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).type(MediaType.TEXT_PLAIN).
               entity(e.getMessage()).build();
      }
    }
    return null;
  }

  private Map<String, List<String>> getHeaderParamsToForward(HttpHeaders headers) {
    Map<String, List<String>> headerParamsToForward = new HashMap<String, List<String>>();
    for (String paramName: headers.getRequestHeaders().keySet()) {
      if (paramName.startsWith(AMBARI_PROXY_PREFIX)) {
        headerParamsToForward.put(paramName.replaceAll(AMBARI_PROXY_PREFIX,""), headers.getRequestHeader(paramName));
      }
    }
    return headerParamsToForward;
  }

}
