/*
 * 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.Sets;
import org.apache.drill.common.expression.CastExpression;
import org.apache.drill.common.expression.FunctionCall;
import org.apache.drill.common.expression.FunctionHolderExpression;
import org.apache.drill.common.expression.IfExpression;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.expression.SchemaPath;

import org.apache.drill.common.expression.visitors.AbstractExprVisitor;

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

/**
 * Class PathInExpr is to recursively analyze a expression trees with a map of
 * indexed expression collected from indexDescriptor, e.g. Map 'cast(a.q as
 * int)' -> '$0' means the expression 'cast(a.q as int)' is named as '$0' in
 * index table.
 * <p>
 * for project expressions: cast(a.q as int), a.q, b + c, PathInExpr will get
 * remainderPath {a.q, b, c}, which is helpful to determine if q query is
 * covering. remainderPathsInFunction will be {a.q}, which will be used to
 * decide if the {a.q} in scan column and project rowtype should be removed or
 * not.
 * <p>
 * This class could be more generic to support any expression, for now it works
 * for only 'cast(schemapath as type)'.
 */
public class PathInExpr extends AbstractExprVisitor<Boolean,Void,RuntimeException> {

  //functional index fields and their involved SchemaPaths
  final private Map<LogicalExpression, Set<SchemaPath>> pathsInExpr;

  //collection of paths in all functional indexes
  private final Set<SchemaPath> allPaths;

  //the paths were found out of functional index expressions in query.
  private final Set<LogicalExpression> remainderPaths;

  //the paths in functional index fields but were found out of index functions expression in query
  private final Set<LogicalExpression> remainderPathsInFunctions;

  //constructor is provided a map of all functional expressions to the paths involved in  the expressions.
  public PathInExpr(Map<LogicalExpression, Set<SchemaPath>> pathsInExpr) {
    this.pathsInExpr = pathsInExpr;
    allPaths = Sets.newHashSet();
    remainderPaths = Sets.newHashSet();
    remainderPathsInFunctions = Sets.newHashSet();
    for(Map.Entry<LogicalExpression, Set<SchemaPath>> entry: pathsInExpr.entrySet()) {
      allPaths.addAll(entry.getValue());
    }
  }

  public Set<LogicalExpression> getRemainderPaths() {
    return remainderPaths;
  }

  public Set<LogicalExpression> getRemainderPathsInFunctions() {
    return remainderPathsInFunctions;
  }

  private boolean preProcess(LogicalExpression inExpr) {
    if (pathsInExpr.containsKey(inExpr)) {
      return true;
    }
    return false;
  }

  @Override
  public Boolean visitFunctionCall(FunctionCall call, Void value) throws RuntimeException {
    if (preProcess(call)) {
      //when it is true, we know this is exactly the indexed expression, no more deep search
      return true;
    }

    boolean bret = true;
    for (LogicalExpression arg : call.args()) {
      bret &= arg.accept(this, null);
      if(bret == false) {
        break;
      }
    }
    return bret;
  }

  @Override
  public Boolean visitFunctionHolderExpression(FunctionHolderExpression holder, Void value) throws RuntimeException {
    if (preProcess(holder)) {
      //when it is true, we know this is exactly the indexed expression, no more deep search
      return true;
    }
    for (LogicalExpression arg : holder.args) {
      arg.accept(this, null);
    }
    return null;
  }

  @Override
  public Boolean visitCastExpression(CastExpression castExpr, Void value) throws RuntimeException {
    if (preProcess(castExpr)) {
      //when it is true, we know this is exactly the indexed expression, no more deep search
      return true;
    }
    return castExpr.getInput().accept(this, null);
  }

  @Override
  public Boolean visitIfExpression(IfExpression ifExpr, Void value) throws RuntimeException {
    return (ifExpr.ifCondition.condition.accept(this, null)
        && ifExpr.ifCondition.expression.accept(this, null)
        && ifExpr.elseExpression.accept(this, null));
  }

  @Override
  public Boolean visitSchemaPath(SchemaPath path, Void value) throws RuntimeException {
    // we can come to here means this path was found out of indexed expressions,
    // so there is a path from query is not covered in functions
    remainderPaths.add(path);

    if(allPaths.contains(path)) {
      // 'path' is a path involved in a functional index field,
      remainderPathsInFunctions.add(path);

      return false;
    }
    //it is not in
    return true;
  }

  @Override
  public Boolean visitUnknown(LogicalExpression e, Void value) throws RuntimeException {
    return true;
  }
}
