/*
 * 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.druid.query;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Ordering;
import org.apache.druid.guice.annotations.ExtensionPoint;
import org.apache.druid.java.util.common.granularity.Granularity;
import org.apache.druid.query.datasourcemetadata.DataSourceMetadataQuery;
import org.apache.druid.query.filter.DimFilter;
import org.apache.druid.query.groupby.GroupByQuery;
import org.apache.druid.query.metadata.metadata.SegmentMetadataQuery;
import org.apache.druid.query.scan.ScanQuery;
import org.apache.druid.query.search.SearchQuery;
import org.apache.druid.query.select.SelectQuery;
import org.apache.druid.query.spec.QuerySegmentSpec;
import org.apache.druid.query.timeboundary.TimeBoundaryQuery;
import org.apache.druid.query.timeseries.TimeseriesQuery;
import org.apache.druid.query.topn.TopNQuery;
import org.apache.druid.segment.Segment;
import org.apache.druid.segment.VirtualColumns;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import org.joda.time.Interval;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

@ExtensionPoint
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "queryType")
@JsonSubTypes(value = {
    @JsonSubTypes.Type(name = Query.TIMESERIES, value = TimeseriesQuery.class),
    @JsonSubTypes.Type(name = Query.SEARCH, value = SearchQuery.class),
    @JsonSubTypes.Type(name = Query.TIME_BOUNDARY, value = TimeBoundaryQuery.class),
    @JsonSubTypes.Type(name = Query.GROUP_BY, value = GroupByQuery.class),
    @JsonSubTypes.Type(name = Query.SCAN, value = ScanQuery.class),
    @JsonSubTypes.Type(name = Query.SEGMENT_METADATA, value = SegmentMetadataQuery.class),
    @JsonSubTypes.Type(name = Query.SELECT, value = SelectQuery.class),
    @JsonSubTypes.Type(name = Query.TOPN, value = TopNQuery.class),
    @JsonSubTypes.Type(name = Query.DATASOURCE_METADATA, value = DataSourceMetadataQuery.class)

})
public interface Query<T>
{
  String TIMESERIES = "timeseries";
  String SEARCH = "search";
  String TIME_BOUNDARY = "timeBoundary";
  String GROUP_BY = "groupBy";
  String SCAN = "scan";
  String SEGMENT_METADATA = "segmentMetadata";
  String SELECT = "select";
  String TOPN = "topN";
  String DATASOURCE_METADATA = "dataSourceMetadata";

  DataSource getDataSource();

  boolean hasFilters();

  DimFilter getFilter();

  String getType();

  QueryRunner<T> getRunner(QuerySegmentWalker walker);

  List<Interval> getIntervals();

  Duration getDuration();

  // currently unused, but helping enforce the idea that all queries have a Granularity
  @SuppressWarnings("unused")
  Granularity getGranularity();

  DateTimeZone getTimezone();

  Map<String, Object> getContext();

  <ContextType> ContextType getContextValue(String key);

  <ContextType> ContextType getContextValue(String key, ContextType defaultValue);

  boolean getContextBoolean(String key, boolean defaultValue);

  boolean isDescending();

  /**
   * Comparator that represents the order in which results are generated from the
   * {@link QueryRunnerFactory#createRunner(Segment)} and
   * {@link QueryRunnerFactory#mergeRunners(QueryProcessingPool, Iterable)} calls. This is used to combine streams of
   * results from different sources; for example, it's used by historicals to combine streams from different segments,
   * and it's used by the broker to combine streams from different historicals.
   *
   * Important note: sometimes, this ordering is used in a type-unsafe way to order @{code Result<BySegmentResultValue>}
   * objects. Because of this, implementations should fall back to {@code Ordering.natural()} when they are given an
   * object that is not of type T.
   */
  Ordering<T> getResultOrdering();

  Query<T> withOverriddenContext(Map<String, Object> contextOverride);

  /**
   * Returns a new query, identical to this one, but with a different associated {@link QuerySegmentSpec}.
   *
   * This often changes the behavior of {@link #getRunner(QuerySegmentWalker)}, since most queries inherit that method
   * from {@link BaseQuery}, which implements it by calling {@link QuerySegmentSpec#lookup}.
   */
  Query<T> withQuerySegmentSpec(QuerySegmentSpec spec);

  Query<T> withId(String id);

  @Nullable
  String getId();

  /**
   * Returns a copy of this query with a new subQueryId (see {@link #getSubQueryId()}.
   */
  Query<T> withSubQueryId(String subQueryId);

  default Query<T> withDefaultSubQueryId()
  {
    return withSubQueryId(UUID.randomUUID().toString());
  }

  /**
   * Returns the subQueryId of this query. This is set by ClientQuerySegmentWalker (the entry point for the Broker's
   * query stack) on any subqueries that it issues. It is null for the main query.
   */
  @Nullable
  String getSubQueryId();

  default Query<T> withSqlQueryId(String sqlQueryId)
  {
    return this;
  }

  @Nullable
  default String getSqlQueryId()
  {
    return null;
  }

  /**
   * Returns a most specific ID of this query; if it is a subquery, this will return its subquery ID.
   * If it is a regular query without subqueries, this will return its query ID.
   * This method should be called after the relevant ID is assigned using {@link #withId} or {@link #withSubQueryId}.
   */
  default String getMostSpecificId()
  {
    final String subqueryId = getSubQueryId();
    return subqueryId == null ? Preconditions.checkNotNull(getId(), "queryId") : subqueryId;
  }

  Query<T> withDataSource(DataSource dataSource);

  default Query<T> optimizeForSegment(PerSegmentQueryOptimizationContext optimizationContext)
  {
    return this;
  }

  default Query<T> withPriority(int priority)
  {
    return withOverriddenContext(ImmutableMap.of(QueryContexts.PRIORITY_KEY, priority));
  }

  default Query<T> withLane(String lane)
  {
    return withOverriddenContext(ImmutableMap.of(QueryContexts.LANE_KEY, lane));
  }

  default VirtualColumns getVirtualColumns()
  {
    return VirtualColumns.EMPTY;
  }

  /**
   * Returns the set of columns that this query will need to access out of its datasource.
   *
   * This method does not "look into" what the datasource itself is doing. For example, if a query is built on a
   * {@link QueryDataSource}, this method will not return the columns used by that subquery. As another example, if a
   * query is built on a {@link JoinDataSource}, this method will not return the columns from the underlying datasources
   * that are used by the join condition, unless those columns are also used by this query in other ways.
   *
   * Returns null if the set of required columns cannot be known ahead of time.
   */
  @Nullable
  default Set<String> getRequiredColumns()
  {
    return null;
  }
}
