/*
 * 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.solr.handler.component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.lucene.search.Query;
import org.apache.lucene.search.grouping.SearchGroup;
import org.apache.lucene.search.grouping.TopGroups;
import org.apache.lucene.util.BytesRef;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.CursorMark;
import org.apache.solr.search.DocListAndSet;
import org.apache.solr.search.DocSlice;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QueryCommand;
import org.apache.solr.search.QueryResult;
import org.apache.solr.search.RankQuery;
import org.apache.solr.search.SortSpec;
import org.apache.solr.search.grouping.GroupingSpecification;
import org.apache.solr.search.grouping.distributed.command.QueryCommandResult;
import org.apache.solr.util.RTimer;

/**
 * This class is experimental and will be changing in the future.
 *
 *
 * @since solr 1.3
 */
public class ResponseBuilder
{
  public SolrQueryRequest req;
  public SolrQueryResponse rsp;
  public boolean doHighlights;
  public boolean doFacets;
  public boolean doExpand;
  public boolean doStats;
  public boolean doTerms;
  public boolean doAnalytics;
  public MergeStrategy mergeFieldHandler;

  private boolean needDocList = false;
  private boolean needDocSet = false;
  private int fieldFlags = 0;
  //private boolean debug = false;
  private boolean debugTimings, debugQuery, debugResults, debugTrack;

  private QParser qparser = null;
  private String queryString = null;
  private Query query = null;
  private List<Query> filters = null;
  private SortSpec sortSpec = null;
  private GroupingSpecification groupingSpec;
  private CursorMark cursorMark;
  private CursorMark nextCursorMark;

  private List<MergeStrategy> mergeStrategies;
  private RankQuery rankQuery;


  private DocListAndSet results = null;
  private NamedList<Object> debugInfo = null;
  private RTimer timer = null;

  private Query highlightQuery = null;

  public List<SearchComponent> components;

  SolrRequestInfo requestInfo;

  public ResponseBuilder(SolrQueryRequest req, SolrQueryResponse rsp, List<SearchComponent> components)
  {
    this.req = req;
    this.rsp = rsp;
    this.components = components;
    this.requestInfo = SolrRequestInfo.getRequestInfo();
  }

  //////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////
  //// Distributed Search section
  //////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////

  public static final String FIELD_SORT_VALUES = "fsv";
  public static final String SHARDS = "shards";
  public static final String IDS = "ids";

  /**
   * public static final String NUMDOCS = "nd";
   * public static final String DOCFREQS = "tdf";
   * public static final String TERMS = "terms";
   * public static final String EXTRACT_QUERY_TERMS = "eqt";
   * public static final String LOCAL_SHARD = "local";
   * public static final String DOC_QUERY = "dq";
   * *
   */

  public static int STAGE_START = 0;
  public static int STAGE_PARSE_QUERY = 1000;
  public static int STAGE_TOP_GROUPS = 1500;
  public static int STAGE_EXECUTE_QUERY = 2000;
  public static int STAGE_GET_FIELDS = 3000;
  public static int STAGE_DONE = Integer.MAX_VALUE;

  public int stage;  // What stage is this current request at?

  //The address of the Shard
  boolean isDistrib; // is this a distributed search?
  public String[] shards;
  public String[] slices; // the optional logical ids of the shards
  public int shards_rows = -1;
  public int shards_start = -1;
  public List<ShardRequest> outgoing;  // requests to be sent
  public List<ShardRequest> finished;  // requests that have received responses from all shards
  public String shortCircuitedURL;

  /**
   * This function will return true if this was a distributed search request.
   */
  public boolean isDistributed() {
    return this.isDistrib;
  }

  public int getShardNum(String shard) {
    for (int i = 0; i < shards.length; i++) {
      if (shards[i] == shard || shards[i].equals(shard)) return i;
    }
    return -1;
  }

  public void addRequest(SearchComponent me, ShardRequest sreq) {
    outgoing.add(sreq);
    if ((sreq.purpose & ShardRequest.PURPOSE_PRIVATE) == 0) {
      // if this isn't a private request, let other components modify it.
      for (SearchComponent component : components) {
        if (component != me) {
          component.modifyRequest(this, me, sreq);
        }
      }
    }
  }

  public Map<Object, ShardDoc> resultIds;
  // Maps uniqueKeyValue to ShardDoc, which may be used to
  // determine order of the doc or uniqueKey in the final
  // returned sequence.
  // Only valid after STAGE_EXECUTE_QUERY has completed.

  public boolean onePassDistributedQuery;

  public FacetComponent.FacetInfo _facetInfo;
  /* private... components that don't own these shouldn't use them */
  SolrDocumentList _responseDocs;
  StatsInfo _statsInfo;
  TermsComponent.TermsHelper _termsHelper;
  SimpleOrderedMap<List<NamedList<Object>>> _pivots;
  Object _analyticsRequestManager;
  boolean _isOlapAnalytics;

  // Context fields for grouping
  public final Map<String, Collection<SearchGroup<BytesRef>>> mergedSearchGroups = new HashMap<>();
  public final Map<String, Long> mergedGroupCounts = new HashMap<>();
  public final Map<String, Map<SearchGroup<BytesRef>, Set<String>>> searchGroupToShards = new HashMap<>();
  public final Map<String, TopGroups<BytesRef>> mergedTopGroups = new HashMap<>();
  public final Map<String, QueryCommandResult> mergedQueryCommandResults = new HashMap<>();
  public final Map<Object, SolrDocument> retrievedDocuments = new HashMap<>();
  public long totalHitCount; // Hit count used when distributed grouping is performed.
  // Used for timeAllowed parameter. First phase elapsed time is subtracted from the time allowed for the second phase.
  public int firstPhaseElapsedTime;

  /**
   * Utility function to add debugging info.  This will make sure a valid
   * debugInfo exists before adding to it.
   */
  public void addDebugInfo( String name, Object val )
  {
    if( debugInfo == null ) {
      debugInfo = new SimpleOrderedMap<>();
    }
    debugInfo.add( name, val );
  }

  public void addDebug(Object val, String... path) {
    if( debugInfo == null ) {
      debugInfo = new SimpleOrderedMap<>();
    }

    NamedList<Object> target = debugInfo;
    for (int i=0; i<path.length-1; i++) {
      String elem = path[i];
      NamedList<Object> newTarget = (NamedList<Object>)debugInfo.get(elem);
      if (newTarget == null) {
        newTarget = new SimpleOrderedMap<>();
        target.add(elem, newTarget);
      }
      target = newTarget;
    }

    target.add(path[path.length-1], val);
  }

  //-------------------------------------------------------------------------
  //-------------------------------------------------------------------------

  public boolean isDebug() {
    return debugQuery || debugTimings || debugResults || debugTrack;
  }

  /**
   *
   * @return true if all debugging options are on
   */
  public boolean isDebugAll(){
    return debugQuery && debugTimings && debugResults && debugTrack;
  }

  public void setDebug(boolean dbg){
    debugQuery = dbg;
    debugTimings = dbg;
    debugResults = dbg;
    debugTrack = dbg;
  }

  public void addMergeStrategy(MergeStrategy mergeStrategy) {
    if(mergeStrategies == null) {
      mergeStrategies = new ArrayList();
    }

    mergeStrategies.add(mergeStrategy);
  }

  public List<MergeStrategy> getMergeStrategies() {
    return this.mergeStrategies;
  }

  public RankQuery getRankQuery() {
    return rankQuery;
  }

  public void setRankQuery(RankQuery rankQuery) {
    this.rankQuery = rankQuery;
  }

  public void setResponseDocs(SolrDocumentList _responseDocs) {
    this._responseDocs = _responseDocs;
  }
  
  public SolrDocumentList getResponseDocs() {
    return this._responseDocs;
  }

  public boolean isDebugTrack() {
    return debugTrack;
  }

  public void setDebugTrack(boolean debugTrack) {
    this.debugTrack = debugTrack;
  }

  public boolean isDebugTimings() {
    return debugTimings;
  }

  public void setDebugTimings(boolean debugTimings) {
    this.debugTimings = debugTimings;
  }

  public boolean isDebugQuery() {
    return debugQuery;
  }

  public void setDebugQuery(boolean debugQuery) {
    this.debugQuery = debugQuery;
  }

  public boolean isDebugResults() {
    return debugResults;
  }

  public void setDebugResults(boolean debugResults) {
    this.debugResults = debugResults;
  }

  public NamedList<Object> getDebugInfo() {
    return debugInfo;
  }

  public void setDebugInfo(NamedList<Object> debugInfo) {
    this.debugInfo = debugInfo;
  }

  public int getFieldFlags() {
    return fieldFlags;
  }

  public void setFieldFlags(int fieldFlags) {
    this.fieldFlags = fieldFlags;
  }

  public List<Query> getFilters() {
    return filters;
  }

  public void setFilters(List<Query> filters) {
    this.filters = filters;
  }

  public Query getHighlightQuery() {
    return highlightQuery;
  }

  public void setHighlightQuery(Query highlightQuery) {
    this.highlightQuery = highlightQuery;
  }

  public boolean isNeedDocList() {
    return needDocList;
  }

  public void setNeedDocList(boolean needDocList) {
    this.needDocList = needDocList;
  }

  public boolean isNeedDocSet() {
    return needDocSet;
  }

  public void setNeedDocSet(boolean needDocSet) {
    this.needDocSet = needDocSet;
  }

  public QParser getQparser() {
    return qparser;
  }

  public void setQparser(QParser qparser) {
    this.qparser = qparser;
  }

  public String getQueryString() {
    return queryString;
  }

  public void setQueryString(String qstr) {
    this.queryString = qstr;
  }

  public Query getQuery() {
    return query;
  }

  public void setQuery(Query query) {
    this.query = query;
  }

  public DocListAndSet getResults() {
    return results;
  }

  public void setResults(DocListAndSet results) {
    this.results = results;
  }

  public SortSpec getSortSpec() {
    return sortSpec;
  }

  public void setSortSpec(SortSpec sortSpec) {
    this.sortSpec = sortSpec;
  }

  public GroupingSpecification getGroupingSpec() {
    return groupingSpec;
  }

  public void setGroupingSpec(GroupingSpecification groupingSpec) {
    this.groupingSpec = groupingSpec;
  }

  public boolean grouping() {
    return groupingSpec != null;
  }

  public RTimer getTimer() {
    return timer;
  }

  public void setTimer(RTimer timer) {
    this.timer = timer;
  }

  /**
   * Creates a SolrIndexSearcher.QueryCommand from this
   * ResponseBuilder.  TimeAllowed is left unset.
   */
  public QueryCommand createQueryCommand() {
    QueryCommand cmd = new QueryCommand();
    cmd.setQuery(wrap(getQuery()))
            .setFilterList(getFilters())
            .setSort(getSortSpec().getSort())
            .setOffset(getSortSpec().getOffset())
            .setLen(getSortSpec().getCount())
            .setFlags(getFieldFlags())
            .setNeedDocSet(isNeedDocSet())
            .setCursorMark(getCursorMark());
    return cmd;
  }

  /** Calls {@link RankQuery#wrap(Query)} if there's a rank query, otherwise just returns the query. */
  public Query wrap(Query q) {
    if(this.rankQuery != null) {
      return this.rankQuery.wrap(q);
    } else {
      return q;
    }
  }

  /**
   * Sets results from a SolrIndexSearcher.QueryResult.
   */
  public void setResult(QueryResult result) {
    setResults(result.getDocListAndSet());
    if (result.isPartialResults()) {
      rsp.getResponseHeader().asShallowMap()
          .put(SolrQueryResponse.RESPONSE_HEADER_PARTIAL_RESULTS_KEY, Boolean.TRUE);
      if(getResults() != null && getResults().docList==null) {
        getResults().docList = new DocSlice(0, 0, new int[] {}, new float[] {}, 0, 0);
      }
    }
    final Boolean segmentTerminatedEarly = result.getSegmentTerminatedEarly();
    if (segmentTerminatedEarly != null) {
      rsp.getResponseHeader().add(SolrQueryResponse.RESPONSE_HEADER_SEGMENT_TERMINATED_EARLY_KEY, segmentTerminatedEarly);
    }
    if (null != cursorMark) {
      assert null != result.getNextCursorMark() : "using cursor but no next cursor set";
      this.setNextCursorMark(result.getNextCursorMark());
    }
  }
  
  public long getNumberDocumentsFound() {
    if (_responseDocs == null) {
      return 0;
    }
    return _responseDocs.getNumFound();
  }

  public CursorMark getCursorMark() {
    return cursorMark;
  }
  public void setCursorMark(CursorMark cursorMark) {
    this.cursorMark = cursorMark;
  }

  public CursorMark getNextCursorMark() {
    return nextCursorMark;
  }
  public void setNextCursorMark(CursorMark nextCursorMark) {
    this.nextCursorMark = nextCursorMark;
  }

  public void setAnalytics(boolean doAnalytics) {
    this.doAnalytics = doAnalytics;
  }

  public boolean isAnalytics() {
    return this.doAnalytics;
  }

  public void setAnalyticsRequestManager(Object analyticsRequestManager) {
    this._analyticsRequestManager = analyticsRequestManager;
  }

  public Object getAnalyticsRequestManager() {
    return this._analyticsRequestManager;
  }

  public void setOlapAnalytics(boolean isOlapAnalytics) {
    this._isOlapAnalytics = isOlapAnalytics;
  }

  public boolean isOlapAnalytics() {
    return this._isOlapAnalytics;
  }
}
