/*
 * 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.store.jdbc;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.calcite.adapter.jdbc.JdbcSchema;
import org.apache.calcite.schema.Function;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Table;
import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlDialect;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.commons.lang3.StringUtils;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.exec.physical.base.PhysicalOperator;
import org.apache.drill.exec.physical.base.Writer;
import org.apache.drill.exec.planner.logical.CreateTableEntry;
import org.apache.drill.exec.planner.logical.ModifyTableEntry;
import org.apache.drill.exec.planner.sql.parser.SqlDropTable;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.StorageStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CapitalizingJdbcSchema extends AbstractSchema {

  private static final Logger logger = LoggerFactory.getLogger(CapitalizingJdbcSchema.class);

  private final Map<String, CapitalizingJdbcSchema> schemaMap;
  private final JdbcSchema inner;
  private final boolean caseSensitive;
  private final JdbcStoragePlugin plugin;
  private final String catalog;
  private final String schema;

  public CapitalizingJdbcSchema(List<String> parentSchemaPath, String name,
                          DataSource dataSource,
                         SqlDialect dialect, DrillJdbcConvention convention, String catalog, String schema, boolean caseSensitive) {
    super(parentSchemaPath, name);
    this.schemaMap = new HashMap<>();
    this.inner = new JdbcSchema(dataSource, dialect, convention, catalog, schema);
    this.caseSensitive = caseSensitive;
    this.plugin = convention.getPlugin();
    this.schema = schema;
    this.catalog = catalog;
  }

  @Override
  public String getTypeName() {
    return JdbcStorageConfig.NAME;
  }

  @Override
  public Collection<Function> getFunctions(String name) {
    return inner.getFunctions(name);
  }

  @Override
  public Set<String> getFunctionNames() {
    return inner.getFunctionNames();
  }

  @Override
  public CapitalizingJdbcSchema getSubSchema(String name) {
    return schemaMap.get(name);
  }

  void setHolder(SchemaPlus plusOfThis) {
    for (String s : getSubSchemaNames()) {
      CapitalizingJdbcSchema inner = getSubSchema(s);
      SchemaPlus holder = plusOfThis.add(s, inner);
      inner.setHolder(holder);
    }
  }

  @Override
  public Set<String> getSubSchemaNames() {
    return schemaMap.keySet();
  }

  @Override
  public Set<String> getTableNames() {
    if (isCatalogSchema()) {
      return Collections.emptySet();
    }
    return inner.getTableNames();
  }


  @Override
  public CreateTableEntry createNewTable(String tableName, List<String> partitionColumns, StorageStrategy strategy) {
    if (plugin.getConfig().isWritable() == null || (! plugin.getConfig().isWritable())) {
      throw UserException
        .dataWriteError()
        .message(plugin.getName() + " is not writable.")
        .build(logger);
    }

    return new CreateTableEntry() {

      @Override
      public Writer getWriter(PhysicalOperator child) {
        return new JdbcWriter(child, getFullTablePath(tableName), inner, plugin);
      }

      @Override
      public List<String> getPartitionColumns() {
        return Collections.emptyList();
      }
    };
  }

  @Override
  public ModifyTableEntry modifyTable(String tableName) {
    return child -> new JdbcInsertWriter(child, getFullTablePath(tableName), inner, plugin);
  }

  @Override
  public void dropTable(String tableName) {
    if (! plugin.getConfig().isWritable()) {
      throw UserException
        .dataWriteError()
        .message(plugin.getName() + " is not writable.")
        .build(logger);
    }

    List<String> names = getFullTablePath(tableName);
    SqlCall dropCall = SqlDropTable.OPERATOR.createCall(
      SqlParserPos.ZERO,
      new SqlIdentifier(names, SqlParserPos.ZERO),
      SqlLiteral.createBoolean(false, SqlParserPos.ZERO)
    );
    String dropTableQuery = dropCall.toSqlString(inner.dialect).getSql();

    try (Connection conn = inner.getDataSource().getConnection();
         Statement stmt = conn.createStatement()) {
      logger.debug("Executing drop table query: {}", dropTableQuery);
      int successfullyDropped = stmt.executeUpdate(dropTableQuery);
      logger.debug("Result: {}", successfullyDropped);
      if (successfullyDropped > 0) {
        throw UserException.dataWriteError()
          .message("Error while dropping table " + tableName)
          .addContext(stmt.getWarnings().getMessage())
          .build(logger);
      }
    } catch (SQLException e) {
      throw UserException.dataWriteError(e)
        .message("Failure while trying to drop table '%s'.", tableName)
        .addContext("plugin", name)
        .build(logger);
    }
  }

  private List<String> getFullTablePath(String tableName) {
    List<String> names = new ArrayList<>();
    if (!StringUtils.isEmpty(catalog)) {
      names.add(catalog);
    }
    if (!StringUtils.isEmpty(schema)) {
      names.add(schema);
    }
    names.add(tableName);
    return names;
  }

  @Override
  public boolean isMutable() {
    return plugin.getConfig().isWritable();
  }

  @Override
  public Table getTable(String name) {
    if (isCatalogSchema()) {
      logger.warn("Failed attempt to find table '{}' in catalog schema '{}'", name, getName());
      return null;
    }
    Table table = inner.getTable(name);
    if (table == null && !areTableNamesCaseSensitive()) {
      // Oracle and H2 changes unquoted identifiers to uppercase.
      table = inner.getTable(name.toUpperCase());
      if (table == null) {
        // Postgres changes unquoted identifiers to lowercase.
        table = inner.getTable(name.toLowerCase());
      }
    }
    return table;
  }

  @Override
  public boolean areTableNamesCaseSensitive() {
    return caseSensitive;
  }

  @Override
  public CapitalizingJdbcSchema getDefaultSchema() {
    return isCatalogSchema()
        ? schemaMap.values().iterator().next().getDefaultSchema()
        : this;
  }

  private boolean isCatalogSchema() {
    return !schemaMap.isEmpty();
  }

  void addSubSchema(CapitalizingJdbcSchema subSchema) {
    schemaMap.put(subSchema.getName(), subSchema);
  }
}
