/*
 * 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.drill.exec.planner.index;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.drill.common.expression.CastExpression;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.expression.SchemaPath;

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

public class MapRDBFunctionalIndexInfo implements FunctionalIndexInfo {

  final private IndexDescriptor indexDesc;

  private boolean hasFunctionalField = false;

  // When we scan schemaPath in groupscan's columns, we check if this column(schemaPath) should be rewritten to '$N',
  // When there are more than two functions on the same column in index, CAST(a.b as INT), CAST(a.b as VARCHAR),
  // then we should map SchemaPath a.b to a set of SchemaPath, e.g. $1, $2
  private Map<SchemaPath, Set<SchemaPath>> columnToConvert;

  // map of functional index expression to destination SchemaPath e.g. $N
  private Map<LogicalExpression, LogicalExpression> exprToConvert;

  // map of SchemaPath involved in a functional field
  private Map<LogicalExpression, Set<SchemaPath>> pathsInExpr;

  private Set<SchemaPath> newPathsForIndexedFunction;

  private Set<SchemaPath> allPathsInFunction;

  public MapRDBFunctionalIndexInfo(IndexDescriptor indexDesc) {
    this.indexDesc = indexDesc;
    columnToConvert = Maps.newHashMap();
    exprToConvert = Maps.newHashMap();
    pathsInExpr = Maps.newHashMap();
    // keep the order of new paths, it may be related to the naming policy
    newPathsForIndexedFunction = Sets.newLinkedHashSet();
    allPathsInFunction = Sets.newHashSet();
    init();
  }

  private void init() {
    int count = 0;
    for (LogicalExpression indexedExpr : indexDesc.getIndexColumns()) {
      if (!(indexedExpr instanceof SchemaPath)) {
        hasFunctionalField = true;
        SchemaPath functionalFieldPath = SchemaPath.getSimplePath("$"+count);
        newPathsForIndexedFunction.add(functionalFieldPath);

        // now we handle only cast expression
        if (indexedExpr instanceof CastExpression) {
          // We handle only CAST directly on SchemaPath for now.
          SchemaPath pathBeingCasted = (SchemaPath)((CastExpression) indexedExpr).getInput();
          addTargetPathForOriginalPath(pathBeingCasted, functionalFieldPath);
          addPathInExpr(indexedExpr, pathBeingCasted);
          exprToConvert.put(indexedExpr, functionalFieldPath);
          allPathsInFunction.add(pathBeingCasted);
        }

        count++;
      }
    }
  }

  private void addPathInExpr(LogicalExpression expr, SchemaPath path) {
    if (!pathsInExpr.containsKey(expr)) {
      Set<SchemaPath> newSet = Sets.newHashSet();
      newSet.add(path);
      pathsInExpr.put(expr, newSet);
    }
    else {
      pathsInExpr.get(expr).add(path);
    }
  }

  private void addTargetPathForOriginalPath(SchemaPath origPath, SchemaPath newPath) {
    if (!columnToConvert.containsKey(origPath)) {
      Set<SchemaPath> newSet = Sets.newHashSet();
      newSet.add(newPath);
      columnToConvert.put(origPath, newSet);
    }
    else {
      columnToConvert.get(origPath).add(newPath);
    }
  }


  public boolean hasFunctional() {
    return hasFunctionalField;
  }

  public IndexDescriptor getIndexDesc() {
    return indexDesc;
  }

  /**
   * getNewPath: for an original path, return new rename '$N' path, notice there could be multiple renamed paths
   * if the there are multiple functional indexes refer original path.
   * @param path
   * @return
   */
  public SchemaPath getNewPath(SchemaPath path) {
    if (columnToConvert.containsKey(path)) {
      return columnToConvert.get(path).iterator().next();
    }
    return null;
  }

  /**
   * return a plain field path if the incoming index expression 'expr' is replaced to be a plain field
   * @param expr suppose to be an indexed expression
   * @return the renamed schemapath in index table for the indexed expression
   */
  public SchemaPath getNewPathFromExpr(LogicalExpression expr) {
    if (exprToConvert.containsKey(expr)) {
      return (SchemaPath)exprToConvert.get(expr);
    }
    return null;
  }

  /**
   * Suppose the index key has functions (rather than plain columns): CAST(a as int), CAST(b as varchar(10)),
   * then we want to maintain a mapping of the logical expression of that function to the schema path of the
   * base column involved in the function. In this example map has 2 entries:
   *   CAST(a as int)  --> 'a'
   *   CAST(b as varchar(10)) --> 'b'
   * @return the map of indexed expression --> the involved schema paths in a indexed expression
   */
  public Map<LogicalExpression, Set<SchemaPath>> getPathsInFunctionExpr() {
    return pathsInExpr;
  }


  public Map<LogicalExpression, LogicalExpression> getExprMap() {
    return exprToConvert;
  }

  public Set<SchemaPath> allNewSchemaPaths() {
    return newPathsForIndexedFunction;
  }

  public Set<SchemaPath> allPathsInFunction() {
    return allPathsInFunction;
  }

  public boolean supportEqualCharConvertToLike() {
    return true;
  }
}
