/*
 * 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.tajo.plan.nameresolver;

import org.apache.tajo.algebra.ColumnReferenceExpr;
import org.apache.tajo.catalog.CatalogUtil;
import org.apache.tajo.catalog.Column;
import org.apache.tajo.catalog.Schema;
import org.apache.tajo.exception.AmbiguousColumnException;
import org.apache.tajo.exception.TajoException;
import org.apache.tajo.exception.UndefinedColumnException;
import org.apache.tajo.plan.LogicalPlan;
import org.apache.tajo.plan.logical.LogicalNode;
import org.apache.tajo.plan.logical.NodeType;
import org.apache.tajo.plan.logical.RelationNode;
import org.apache.tajo.util.Pair;

import java.util.ArrayList;
import java.util.List;

public class ResolverByLegacy extends NameResolver {
  @Override
  public Column resolve(LogicalPlan plan,
                        LogicalPlan.QueryBlock block,
                        ColumnReferenceExpr columnRef,
                        boolean includeSeflDescTable)
      throws TajoException {

    if (columnRef.hasQualifier()) {
      return resolveColumnWithQualifier(plan, block, columnRef, includeSeflDescTable);
    } else {
      return resolveColumnWithoutQualifier(plan, block, columnRef, includeSeflDescTable);
    }
  }

  private static Column resolveColumnWithQualifier(LogicalPlan plan, LogicalPlan.QueryBlock block,
                                                   ColumnReferenceExpr columnRef, boolean includeSeflDescTable)
      throws TajoException {
    final String qualifier;
    final String qualifiedName;

    Pair<String, String> normalized = lookupQualifierAndCanonicalName(block, columnRef, includeSeflDescTable);
    qualifier = normalized.getFirst();
    qualifiedName = CatalogUtil.buildFQName(qualifier, columnRef.getName());

    Column found = resolveFromRelsWithinBlock(plan, block, columnRef, includeSeflDescTable);
    if (found == null) {
      throw new UndefinedColumnException(columnRef.getCanonicalName());
    }

    // If code reach here, a column is found.
    // But, it may be aliased from bottom logical node.
    // If the column is aliased, the found name may not be used in upper node.

    // Here, we try to check if column reference is already aliased.
    // If so, it replaces the name with aliased name.
    LogicalNode currentNode = block.getCurrentNode();

    // The condition (currentNode.getInSchema().contains(column)) means
    // the column can be used at the current node. So, we don't need to find aliase name.
    Schema currentNodeSchema = null;
    if (currentNode != null) {
      if (currentNode instanceof RelationNode) {
        currentNodeSchema = ((RelationNode) currentNode).getLogicalSchema();
      } else {
        currentNodeSchema = currentNode.getInSchema();
      }
    }

    if (currentNode != null && !currentNodeSchema.contains(found)
        && currentNode.getType() != NodeType.TABLE_SUBQUERY) {
      List<Column> candidates = new ArrayList<>();
      if (block.getNamedExprsManager().isAliased(qualifiedName)) {
        String alias = block.getNamedExprsManager().getAlias(qualifiedName);
        found = resolve(plan, block, new ColumnReferenceExpr(alias), NameResolvingMode.LEGACY, includeSeflDescTable);
        if (found != null) {
          candidates.add(found);
        }
      }
      if (!candidates.isEmpty()) {
        return ensureUniqueColumn(candidates);
      }
    }

    return found;
  }

  static Column resolveColumnWithoutQualifier(LogicalPlan plan, LogicalPlan.QueryBlock block,
                                              ColumnReferenceExpr columnRef, boolean includeSeflDescTable)
      throws AmbiguousColumnException, UndefinedColumnException {

    Column found = lookupColumnFromAllRelsInBlock(block, columnRef.getName(), includeSeflDescTable);
    if (found != null) {
      return found;
    }

    found = resolveAliasedName(block, columnRef);
    if (found != null) {
      return found;
    }

    found = resolveFromCurrentAndChildNode(block, columnRef);
    if (found != null) {
      return found;
    }

    found = resolveFromAllRelsInAllBlocks(plan, columnRef);
    if (found != null) {
      return found;
    }

    throw new UndefinedColumnException(columnRef.getCanonicalName());
  }
}
