// 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.impala.analysis;

import java.util.List;

import org.apache.impala.catalog.Catalog;
import org.apache.impala.common.AnalysisException;
import org.apache.impala.compat.MetastoreShim;
import org.apache.impala.thrift.TTableName;

import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.apache.impala.util.CatalogBlacklistUtils;

/**
 * Represents a table/view name that optionally includes its database (a fully qualified
 * table name). Analysis of this table name checks for validity of the database and
 * table name according to the Metastore's policy (see @MetaStoreUtils).
 * According to that definition, we can still use "invalid" table names for tables/views
 * that are not stored in the Metastore, e.g., for Inline Views or WITH-clause views.
 */
public class TableName {
  private final String db_;
  private final String tbl_;

  public TableName(String db, String tbl) {
    super();
    Preconditions.checkArgument(db == null || !db.isEmpty());
    this.db_ = db;
    Preconditions.checkNotNull(tbl);
    this.tbl_ = tbl;
  }

  /**
   * Parse the given full name (in format <db>.<tbl>) and return a TableName object.
   * Return null for any failures. Note that we keep table names in lower case so the
   * string will be converted to lower case first.
   */
  public static TableName parse(String fullName) {
    // Avoid "db1." and ".tbl1" being treated as the same. We resolve ".tbl1" as
    // "default.tbl1". But we reject "db1." since it only gives the database name.
    if (fullName == null || fullName.trim().endsWith(".")) return null;
    // TODO: upgrade Guava to 15+ to use splitToList instead
    List<String> parts = Lists.newArrayList(Splitter.on('.').trimResults()
        .omitEmptyStrings().split(fullName.toLowerCase()));
    if (parts.size() == 1) {
      return new TableName(Catalog.DEFAULT_DB, parts.get(0));
    }
    if (parts.size() == 2) {
      return new TableName(parts.get(0), parts.get(1));
    }
    return null;
  }

  public String getDb() { return db_; }
  public String getTbl() { return tbl_; }
  public boolean isEmpty() { return tbl_.isEmpty(); }

  /**
   * Checks whether the db and table name meet the Metastore's requirements. and not in
   * our blacklist. 'db_' is assumed to be resolved.
   */
  public void analyze() throws AnalysisException {
    Preconditions.checkNotNull(isFullyQualified());
    if (!MetastoreShim.validateName(db_)) {
      throw new AnalysisException("Invalid database name: " + db_);
    }
    if (!MetastoreShim.validateName(tbl_)) {
      throw new AnalysisException("Invalid table/view name: " + tbl_);
    }
    CatalogBlacklistUtils.verifyTableName(this);
  }

  /**
   * Returns true if this name has a non-empty database field and a non-empty
   * table name.
   */
  public boolean isFullyQualified() {
    return db_ != null && !db_.isEmpty() && !tbl_.isEmpty();
  }

  public String toSql() {
    // Enclose the database and/or table name in quotes if Hive cannot parse them
    // without quotes. This is needed for view compatibility between Impala and Hive.
    if (db_ == null) {
      return ToSqlUtils.getIdentSql(tbl_);
    } else {
      return ToSqlUtils.getIdentSql(db_) + "." + ToSqlUtils.getIdentSql(tbl_);
    }
  }

  @Override
  public String toString() {
    if (db_ == null) {
      return tbl_;
    } else {
      return db_ + "." + tbl_;
    }
  }

  public List<String> toPath() {
    List<String> result = Lists.newArrayListWithCapacity(2);
    if (db_ != null) result.add(db_);
    result.add(tbl_);
    return result;
  }

  public static TableName fromThrift(TTableName tableName) {
    return new TableName(tableName.getDb_name(), tableName.getTable_name());
  }

  public TTableName toThrift() { return new TTableName(db_, tbl_); }

  /**
   * Returns true of the table names are considered equals. To check for equality,
   * a case-insensitive comparison of the database and table name is performed.
   */
  @Override
  public boolean equals(Object anObject) {
    if (anObject instanceof TableName) {
      return toString().toLowerCase().equals(anObject.toString().toLowerCase());
    }
    return false;
  }

  @Override
  public int hashCode() {
    return toString().toLowerCase().hashCode();
  }
}
