/* $Id$ */
/* Modified to MCFAuthorizerRestSearchAction.java 2015-04-28 Bart Superson */
/**
* 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.manifoldcf.elasticsearch;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.search.RestSearchAction;
import org.elasticsearch.rest.action.support.RestStatusToXContentListener;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.term.TermSuggestionBuilder;

import java.io.*;

public class MCFAuthorizerRestSearchAction extends RestSearchAction {

  protected final MCFAuthorizer authorizer;
  
  @Inject
  public MCFAuthorizerRestSearchAction(Settings settings, final RestController restController, Client client) {
    super(settings,restController,client);
    final MCFConfigurationParameters conf = new MCFConfigurationParameters(settings);
    authorizer = new MCFAuthorizer(conf);
  }

  @Override
  public void handleRequest(RestRequest request, RestChannel channel, Client client) {
    SearchRequest searchRequest = parseSearchRequestMCF(request);
    //TODO: see if this is still needed??? searchRequest.listenerThreaded(false);
    client.search(searchRequest, new RestStatusToXContentListener(channel));
  }
  
  protected SearchRequest parseSearchRequestMCF(final RestRequest request) throws MCFAuthorizerException {
    SearchRequest searchRequest;
    if(request.param("u")!=null) {
      String[] authenticatedUserNamesAndDomains = request.param("u").split(",");
      String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
      searchRequest = new SearchRequest(indices);
      boolean isTemplateRequest = request.path().endsWith("/template");

      if(request.hasContent() || request.hasParam("source")) {
        QueryBuilder authorizationFilter = authorizer.buildAuthorizationFilter(authenticatedUserNamesAndDomains);
        FilteredQueryBuilder filteredQueryBuilder;

        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode modifiedJSON, innerJSON;
        JsonNode requestJSON;

        try {
          requestJSON = objectMapper.readTree(RestActions.getRestContent(request).toBytes());
          if (isTemplateRequest) {
            modifiedJSON = (ObjectNode) requestJSON;
            innerJSON = (ObjectNode)requestJSON.findValue("template");
            filteredQueryBuilder = QueryBuilders.filteredQuery(QueryBuilders.wrapperQuery(innerJSON.findValue("query").toString()), authorizationFilter);
            modifiedJSON.replace("template",innerJSON.set("query", objectMapper.readTree(filteredQueryBuilder.buildAsBytes().toBytes())));
            searchRequest.templateSource(modifiedJSON.toString());
          } else {
            filteredQueryBuilder = QueryBuilders.filteredQuery(QueryBuilders.wrapperQuery(requestJSON.findValue("query").toString()), authorizationFilter);
            modifiedJSON = (ObjectNode) requestJSON;
            modifiedJSON.set("query", objectMapper.readTree(filteredQueryBuilder.buildAsBytes().toBytes()));
            searchRequest.source(modifiedJSON.toString());
          }
        } catch (IOException e) {
            e.printStackTrace();
            throw new MCFAuthorizerException("JSON parser error");
          }
      }

      searchRequest.extraSource(parseSearchSourceMCF(request));
      searchRequest.searchType(request.param("search_type"));
      //TODO: figure out if we still need this??? searchRequest.queryCache(request.paramAsBoolean("query_cache", (Boolean)null));
      String scroll = request.param("scroll");
      if(scroll != null) {
        //TODO: figure out if we still need this??? searchRequest.scroll(new Scroll(TimeValue.parseTimeValue(scroll, (TimeValue)null)));
      }

      searchRequest.types(Strings.splitStringByCommaToArray(request.param("type")));
      searchRequest.routing(request.param("routing"));
      searchRequest.preference(request.param("preference"));
      searchRequest.indicesOptions(IndicesOptions.fromRequest(request, searchRequest.indicesOptions()));
    }
    else {
      //TODO: we definitely still need this, but its form has dramatically changed, and it now parses into the current body and returns
      // void.  Gotta look at how to rethink plugin architecture given that ???
      searchRequest = RestSearchAction.parseSearchRequest(request);
    }
    return searchRequest;
  }

  protected SearchSourceBuilder parseSearchSourceMCF(final RestRequest request) throws MCFAuthorizerException {
    SearchSourceBuilder searchSourceBuilder = null;
    String queryString = request.param("q");
    if(queryString != null) {
      String[] authenticatedUserNamesAndDomains = request.param("u").split(",");
      QueryBuilder authorizationFilter = authorizer.buildAuthorizationFilter(authenticatedUserNamesAndDomains);
      QueryStringQueryBuilder from = QueryBuilders.queryStringQuery(queryString);
      from.defaultField(request.param("df"));
      from.analyzer(request.param("analyzer"));
      from.analyzeWildcard(request.paramAsBoolean("analyze_wildcard", false));
      from.lowercaseExpandedTerms(request.paramAsBoolean("lowercase_expanded_terms", true));
      from.lenient(request.paramAsBoolean("lenient", (Boolean)null));
      String size = request.param("default_operator");
      if(size != null) {
        if("OR".equals(size)) {
          from.defaultOperator(QueryStringQueryBuilder.Operator.OR);
        } else {
          if(!"AND".equals(size)) {
            throw new IllegalArgumentException("Unsupported defaultOperator [" + size + "], can either be [OR] or [AND]");
          }

          from.defaultOperator(QueryStringQueryBuilder.Operator.AND);
        }
      }

      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.query(QueryBuilders.filteredQuery(from, authorizationFilter));
    }
    else {
        if(!(request.hasContent() || request.hasParam("source"))){
          if(searchSourceBuilder == null) {
            searchSourceBuilder = new SearchSourceBuilder();
          }
          QueryBuilder authorizationFilter = authorizer.buildAuthorizationFilter(request.param("u"));
          searchSourceBuilder.query(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),authorizationFilter));
        }
    }

    int var19 = request.paramAsInt("from", -1);
    if(var19 != -1) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.from(var19);
    }

    int var20 = request.paramAsInt("size", -1);
    if(var20 != -1) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.size(var20);
    }

    if(request.hasParam("explain")) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.explain(request.paramAsBoolean("explain", (Boolean)null));
    }

    if(request.hasParam("version")) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.version(request.paramAsBoolean("version", (Boolean)null));
    }

    if(request.hasParam("timeout")) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.timeout(request.paramAsTime("timeout", (TimeValue)null));
    }

    if(request.hasParam("terminate_after")) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      int sField = request.paramAsInt("terminate_after", 0);
      if(sField < 0) {
        throw new IllegalArgumentException("terminateAfter must be > 0");
      }

      if(sField > 0) {
        searchSourceBuilder.terminateAfter(sField);
      }
    }

    String var21 = request.param("fields");
    String suggestField;
    if(var21 != null) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      if(!Strings.hasText(var21)) {
        searchSourceBuilder.noFields();
      } else {
        String[] fetchSourceContext = Strings.splitStringByCommaToArray(var21);
        if(fetchSourceContext != null) {
          String[] sSorts = fetchSourceContext;
          int sIndicesBoost = fetchSourceContext.length;

          for(int sStats = 0; sStats < sIndicesBoost; ++sStats) {
            suggestField = sSorts[sStats];
            searchSourceBuilder.field(suggestField);
          }
        }
      }
    }

    FetchSourceContext var22 = FetchSourceContext.parseFromRestRequest(request);
    if(var22 != null) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.fetchSource(var22);
    }

    if(request.hasParam("track_scores")) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.trackScores(request.paramAsBoolean("track_scores", false));
    }

    String var23 = request.param("sort");
    int suggestText;
    String indexName;
    String[] var26;
    if(var23 != null) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      String[] var24 = Strings.splitStringByCommaToArray(var23);
      var26 = var24;
      int var27 = var24.length;

      for(suggestText = 0; suggestText < var27; ++suggestText) {
        String suggestSize = var26[suggestText];
        int suggestMode = suggestSize.lastIndexOf(":");
        if(suggestMode != -1) {
          String divisor = suggestSize.substring(0, suggestMode);
          indexName = suggestSize.substring(suggestMode + 1);
          if("asc".equals(indexName)) {
            searchSourceBuilder.sort(divisor, SortOrder.ASC);
          } else if("desc".equals(indexName)) {
            searchSourceBuilder.sort(divisor, SortOrder.DESC);
          }
        } else {
          searchSourceBuilder.sort(suggestSize);
        }
      }
    }

    String var25 = request.param("indices_boost");
    int var31;
    String var32;
    if(var25 != null) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      var26 = Strings.splitStringByCommaToArray(var25);
      String[] var29 = var26;
      suggestText = var26.length;

      for(var31 = 0; var31 < suggestText; ++var31) {
        var32 = var29[var31];
        int var33 = var32.indexOf(44);
        if(var33 == -1) {
          throw new IllegalArgumentException("Illegal index boost [" + var32 + "], no \',\'");
        }

        indexName = var32.substring(0, var33);
        String sBoost = var32.substring(var33 + 1);

        try {
          searchSourceBuilder.indexBoost(indexName, Float.parseFloat(sBoost));
        } catch (NumberFormatException var18) {
          throw new IllegalArgumentException("Illegal index boost [" + var32 + "], boost not a float number");
        }
      }
    }

    String var28 = request.param("stats");
    if(var28 != null) {
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      searchSourceBuilder.stats(Strings.splitStringByCommaToArray(var28));
    }

    suggestField = request.param("suggest_field");
    if(suggestField != null) {
      String var30 = request.param("suggest_text", queryString);
      var31 = request.paramAsInt("suggest_size", 5);
      if(searchSourceBuilder == null) {
        searchSourceBuilder = new SearchSourceBuilder();
      }

      var32 = request.param("suggest_mode");
      searchSourceBuilder.suggest().addSuggestion(((TermSuggestionBuilder)((TermSuggestionBuilder)((TermSuggestionBuilder)SuggestBuilders.termSuggestion(suggestField).field(suggestField)).text(var30)).size(var31)).suggestMode(var32));
    }

    return searchSourceBuilder;
  }

}
