/*
 * 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.iotdb.db.mpp.plan.analyze;

import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSchemaNode;
import org.apache.iotdb.commons.partition.DataPartition;
import org.apache.iotdb.commons.partition.SchemaPartition;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.template.Template;
import org.apache.iotdb.db.mpp.common.header.DatasetHeader;
import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
import org.apache.iotdb.db.mpp.plan.expression.Expression;
import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.FillDescriptor;
import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.GroupByTimeParameter;
import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.OrderByParameter;
import org.apache.iotdb.db.mpp.plan.statement.Statement;
import org.apache.iotdb.tsfile.read.filter.basic.Filter;
import org.apache.iotdb.tsfile.utils.Pair;

import java.util.List;
import java.util.Map;
import java.util.Set;

/** Analysis used for planning a query. TODO: This class may need to store more info for a query. */
public class Analysis {

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // Common Analysis
  /////////////////////////////////////////////////////////////////////////////////////////////////

  // Statement
  private Statement statement;

  // indicate whether this statement is `WRITE` or `READ`
  private QueryType queryType;

  private DataPartition dataPartition;

  private SchemaPartition schemaPartition;

  private ISchemaTree schemaTree;

  // map from output column name (for every node) to its datatype
  private TypeProvider typeProvider;

  private boolean finishQueryAfterAnalyze;

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // Query Analysis (used in ALIGN BY TIME)
  /////////////////////////////////////////////////////////////////////////////////////////////////

  // map from device name to series/aggregation under this device
  private Set<Expression> sourceExpressions;

  // input expressions of aggregations to be calculated
  private Set<Expression> aggregationTransformExpressions;

  // all aggregations that need to be calculated
  private Set<Expression> aggregationExpressions;

  // expression of output column to be calculated
  private Set<Expression> transformExpressions;

  private Expression queryFilter;

  private Expression havingExpression;

  // map from grouped path name to list of input aggregation in `GROUP BY LEVEL` clause
  private Map<Expression, Set<Expression>> groupByLevelExpressions;

  // map from raw path to grouped path in `GROUP BY LEVEL` clause
  private Map<Expression, Expression> rawPathToGroupedPathMap;

  private boolean isRawDataSource;

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // Query Analysis (used in ALIGN BY DEVICE)
  /////////////////////////////////////////////////////////////////////////////////////////////////

  // map from device name to series/aggregation under this device
  private Map<String, Set<Expression>> deviceToSourceExpressions;

  // input expressions of aggregations to be calculated
  private Map<String, Set<Expression>> deviceToAggregationTransformExpressions;

  // all aggregations that need to be calculated
  private Map<String, Set<Expression>> deviceToAggregationExpressions;

  // expression of output column to be calculated
  private Map<String, Set<Expression>> deviceToTransformExpressions;

  // map from device name to query filter under this device
  private Map<String, Expression> deviceToQueryFilter;

  // map from device name to havingExpression under this device
  private Map<String, Expression> deviceToHavingExpression;

  // e.g. [s1,s2,s3] is query, but [s1, s3] exists in device1, then device1 -> [1, 3], s1 is 1 but
  // not 0 because device is the first column
  private Map<String, List<Integer>> deviceToMeasurementIndexesMap;

  private Map<String, Boolean> deviceToIsRawDataSource;

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // Query Common Analysis (above DeviceView)
  /////////////////////////////////////////////////////////////////////////////////////////////////

  // indicate is there a value filter
  private boolean hasValueFilter = false;

  // true if nested expressions and UDFs exist in aggregation function
  private boolean isHasRawDataInputAggregation;

  // a global time filter used in `initQueryDataSource` and filter push down
  private Filter globalTimeFilter;

  // parameter of `FILL` clause
  private FillDescriptor fillDescriptor;

  // parameter of `GROUP BY TIME` clause
  private GroupByTimeParameter groupByTimeParameter;

  // header of result dataset
  private DatasetHeader respDatasetHeader;

  private OrderByParameter mergeOrderParameter;

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // Schema Query Analysis
  /////////////////////////////////////////////////////////////////////////////////////////////////

  // extra mesaage from config node, used for node management
  private Set<TSchemaNode> matchedNodes;

  // template and paths set template
  private Pair<Template, List<PartialPath>> templateSetInfo;

  // potential template used in timeseries query or fetch
  private Map<Integer, Template> relatedTemplateInfo;

  public Analysis() {
    this.finishQueryAfterAnalyze = false;
  }

  public List<TRegionReplicaSet> getPartitionInfo(PartialPath seriesPath, Filter timefilter) {
    // TODO: (xingtanzjr) implement the calculation of timePartitionIdList
    return dataPartition.getDataRegionReplicaSet(seriesPath.getDevice(), null);
  }

  public List<TRegionReplicaSet> getPartitionInfo(String deviceName, Filter globalTimeFilter) {
    return dataPartition.getDataRegionReplicaSet(deviceName, null);
  }

  public Statement getStatement() {
    return statement;
  }

  public void setStatement(Statement statement) {
    this.statement = statement;
  }

  public DataPartition getDataPartitionInfo() {
    return dataPartition;
  }

  public void setDataPartitionInfo(DataPartition dataPartition) {
    this.dataPartition = dataPartition;
  }

  public SchemaPartition getSchemaPartitionInfo() {
    return schemaPartition;
  }

  public void setSchemaPartitionInfo(SchemaPartition schemaPartition) {
    this.schemaPartition = schemaPartition;
  }

  public ISchemaTree getSchemaTree() {
    return schemaTree;
  }

  public void setSchemaTree(ISchemaTree schemaTree) {
    this.schemaTree = schemaTree;
  }

  public Filter getGlobalTimeFilter() {
    return globalTimeFilter;
  }

  public void setGlobalTimeFilter(Filter timeFilter) {
    this.globalTimeFilter = timeFilter;
  }

  public DatasetHeader getRespDatasetHeader() {
    return respDatasetHeader;
  }

  public void setRespDatasetHeader(DatasetHeader respDatasetHeader) {
    this.respDatasetHeader = respDatasetHeader;
  }

  public TypeProvider getTypeProvider() {
    return typeProvider;
  }

  public void setTypeProvider(TypeProvider typeProvider) {
    this.typeProvider = typeProvider;
  }

  public boolean hasDataSource() {
    return (dataPartition != null && !dataPartition.isEmpty())
        || (schemaPartition != null && !schemaPartition.isEmpty());
  }

  public boolean isHasRawDataInputAggregation() {
    return isHasRawDataInputAggregation;
  }

  public void setHasRawDataInputAggregation(boolean hasRawDataInputAggregation) {
    isHasRawDataInputAggregation = hasRawDataInputAggregation;
  }

  public Map<Expression, Set<Expression>> getGroupByLevelExpressions() {
    return groupByLevelExpressions;
  }

  public void setGroupByLevelExpressions(Map<Expression, Set<Expression>> groupByLevelExpressions) {
    this.groupByLevelExpressions = groupByLevelExpressions;
  }

  public void setRawPathToGroupedPathMap(Map<Expression, Expression> rawPathToGroupedPathMap) {
    this.rawPathToGroupedPathMap = rawPathToGroupedPathMap;
  }

  public Expression getGroupedExpressionByLevel(Expression expression) {
    if (rawPathToGroupedPathMap.containsKey(expression)) {
      return rawPathToGroupedPathMap.get(expression);
    }
    if (rawPathToGroupedPathMap.containsValue(expression)) {
      return expression;
    }
    throw new IllegalArgumentException(
        String.format("GROUP BY LEVEL: Unknown input expression '%s'", expression));
  }

  public FillDescriptor getFillDescriptor() {
    return fillDescriptor;
  }

  public void setFillDescriptor(FillDescriptor fillDescriptor) {
    this.fillDescriptor = fillDescriptor;
  }

  public boolean hasValueFilter() {
    return hasValueFilter;
  }

  public void setHasValueFilter(boolean hasValueFilter) {
    this.hasValueFilter = hasValueFilter;
  }

  public Expression getQueryFilter() {
    return queryFilter;
  }

  public void setQueryFilter(Expression queryFilter) {
    this.queryFilter = queryFilter;
  }

  public Map<String, Expression> getDeviceToQueryFilter() {
    return deviceToQueryFilter;
  }

  public void setDeviceToQueryFilter(Map<String, Expression> deviceToQueryFilter) {
    this.deviceToQueryFilter = deviceToQueryFilter;
  }

  public GroupByTimeParameter getGroupByTimeParameter() {
    return groupByTimeParameter;
  }

  public Expression getHavingExpression() {
    return havingExpression;
  }

  public void setHavingExpression(Expression havingExpression) {
    this.havingExpression = havingExpression;
  }

  public Map<String, Expression> getDeviceToHavingExpression() {
    return deviceToHavingExpression;
  }

  public void setDeviceToHavingExpression(Map<String, Expression> deviceTohavingExpression) {
    this.deviceToHavingExpression = deviceTohavingExpression;
  }

  public void setGroupByTimeParameter(GroupByTimeParameter groupByTimeParameter) {
    this.groupByTimeParameter = groupByTimeParameter;
  }

  public boolean isFinishQueryAfterAnalyze() {
    return finishQueryAfterAnalyze;
  }

  public void setFinishQueryAfterAnalyze(boolean finishQueryAfterAnalyze) {
    this.finishQueryAfterAnalyze = finishQueryAfterAnalyze;
  }

  public void setDeviceToMeasurementIndexesMap(
      Map<String, List<Integer>> deviceToMeasurementIndexesMap) {
    this.deviceToMeasurementIndexesMap = deviceToMeasurementIndexesMap;
  }

  public Map<String, List<Integer>> getDeviceToMeasurementIndexesMap() {
    return deviceToMeasurementIndexesMap;
  }

  public Set<Expression> getSourceExpressions() {
    return sourceExpressions;
  }

  public void setSourceExpressions(Set<Expression> sourceExpressions) {
    this.sourceExpressions = sourceExpressions;
  }

  public Set<Expression> getAggregationTransformExpressions() {
    return aggregationTransformExpressions;
  }

  public void setAggregationTransformExpressions(Set<Expression> aggregationTransformExpressions) {
    this.aggregationTransformExpressions = aggregationTransformExpressions;
  }

  public Set<Expression> getAggregationExpressions() {
    return aggregationExpressions;
  }

  public void setAggregationExpressions(Set<Expression> aggregationExpressions) {
    this.aggregationExpressions = aggregationExpressions;
  }

  public Set<Expression> getTransformExpressions() {
    return transformExpressions;
  }

  public void setTransformExpressions(Set<Expression> transformExpressions) {
    this.transformExpressions = transformExpressions;
  }

  public Map<String, Set<Expression>> getDeviceToSourceExpressions() {
    return deviceToSourceExpressions;
  }

  public void setDeviceToSourceExpressions(Map<String, Set<Expression>> deviceToSourceExpressions) {
    this.deviceToSourceExpressions = deviceToSourceExpressions;
  }

  public Map<String, Set<Expression>> getDeviceToAggregationTransformExpressions() {
    return deviceToAggregationTransformExpressions;
  }

  public void setDeviceToAggregationTransformExpressions(
      Map<String, Set<Expression>> deviceToAggregationTransformExpressions) {
    this.deviceToAggregationTransformExpressions = deviceToAggregationTransformExpressions;
  }

  public Map<String, Set<Expression>> getDeviceToAggregationExpressions() {
    return deviceToAggregationExpressions;
  }

  public void setDeviceToAggregationExpressions(
      Map<String, Set<Expression>> deviceToAggregationExpressions) {
    this.deviceToAggregationExpressions = deviceToAggregationExpressions;
  }

  public Map<String, Set<Expression>> getDeviceToTransformExpressions() {
    return deviceToTransformExpressions;
  }

  public void setDeviceToTransformExpressions(
      Map<String, Set<Expression>> deviceToTransformExpressions) {
    this.deviceToTransformExpressions = deviceToTransformExpressions;
  }

  public boolean isRawDataSource() {
    return isRawDataSource;
  }

  public void setRawDataSource(boolean rawDataSource) {
    isRawDataSource = rawDataSource;
  }

  public Map<String, Boolean> getDeviceToIsRawDataSource() {
    return deviceToIsRawDataSource;
  }

  public void setDeviceToIsRawDataSource(Map<String, Boolean> deviceToIsRawDataSource) {
    this.deviceToIsRawDataSource = deviceToIsRawDataSource;
  }

  public Set<TSchemaNode> getMatchedNodes() {
    return matchedNodes;
  }

  public void setMatchedNodes(Set<TSchemaNode> matchedNodes) {
    this.matchedNodes = matchedNodes;
  }

  public OrderByParameter getMergeOrderParameter() {
    return mergeOrderParameter;
  }

  public void setMergeOrderParameter(OrderByParameter mergeOrderParameter) {
    this.mergeOrderParameter = mergeOrderParameter;
  }

  public Pair<Template, List<PartialPath>> getTemplateSetInfo() {
    return templateSetInfo;
  }

  public void setTemplateSetInfo(Pair<Template, List<PartialPath>> templateSetInfo) {
    this.templateSetInfo = templateSetInfo;
  }

  public Map<Integer, Template> getRelatedTemplateInfo() {
    return relatedTemplateInfo;
  }

  public void setRelatedTemplateInfo(Map<Integer, Template> relatedTemplateInfo) {
    this.relatedTemplateInfo = relatedTemplateInfo;
  }
}
