// Copyright 2015 The Android Open Source Project
//
// Licensed 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 com.google.gwtorm.schema.sql;

import com.google.gwtorm.schema.ColumnModel;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.StatementExecutor;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.HashSet;
import java.util.Set;

/** Dialect for DB2 */
public class DialectDB2 extends SqlDialect {

  public DialectDB2() {
    typeNames.put(Types.LONGVARCHAR, "CLOB");
  }

  @Override
  public boolean handles(String url, Connection c) {
    return url.startsWith("jdbc:db2:");
  }

  @Override
  public OrmException convertError(String op, String entity,
      SQLException err) {
    switch (getSQLStateInt(err)) {
      case 23505: // DUPLICATE_KEY_1
        return new OrmDuplicateKeyException(entity, err);

      default:
        return super.convertError(op, entity, err);
    }
  }

  @Override
  protected String getNextSequenceValueSql(String seqname) {
    return "VALUES NEXT VALUE FOR " + seqname;
  }

  @Override
  public Set<String> listSequences(Connection db) throws SQLException {
    Statement s = db.createStatement();
    try {
      ResultSet rs =
          s.executeQuery("SELECT SEQNAME"
              + " FROM SYSCAT.SEQUENCES"
              + " WHERE SEQSCHEMA = CURRENT_SCHEMA");
      try {
        HashSet<String> sequences = new HashSet<>();
        while (rs.next()) {
          sequences.add(rs.getString(1).toLowerCase());
        }
        return sequences;
      } finally {
        rs.close();
      }
    } finally {
      s.close();
    }
  }

  @Override
  public Set<String> listTables(Connection db) throws SQLException {
    Statement s = db.createStatement();
    try {
      ResultSet rs = s.executeQuery("SELECT TABNAME"
          + " FROM SYSCAT.TABLES"
          + " WHERE TABSCHEMA = CURRENT_SCHEMA");
      try {
        Set<String> tables = new HashSet<>();
        while (rs.next()) {
          tables.add(rs.getString(1).toLowerCase());
        }
        return tables;
      } finally {
        rs.close();
      }
    } finally {
      s.close();
    }
  }

  @Override
  public Set<String> listIndexes(final Connection db, String tableName)
      throws SQLException {
    PreparedStatement s = db.prepareStatement("SELECT distinct INDNAME"
        + " FROM syscat.indexes WHERE TABNAME = ? AND TABSCHEMA = CURRENT_SCHEMA");
    try {
      s.setString(1, tableName.toUpperCase());
      ResultSet rs = s.executeQuery();
      try {
        Set<String> indexes = new HashSet<>();
        while (rs.next()) {
          indexes.add(rs.getString(1).toLowerCase());
        }
        return indexes;
      } finally {
        rs.close();
      }
    } finally {
      s.close();
    }
  }

  @Override
  public void renameTable(StatementExecutor e, String from, String to)
      throws OrmException {
    StringBuilder r = new StringBuilder();
    r.append("RENAME TABLE ");
    r.append(from);
    r.append(" TO ");
    r.append(to);
    e.execute(r.toString());
  }

  @Override
  public void renameColumn(StatementExecutor stmt, String tableName,
      String fromColumn, ColumnModel col) throws OrmException {
    StringBuilder r = new StringBuilder();
    r.append("ALTER TABLE ");
    r.append(tableName);
    r.append(" RENAME COLUMN ");
    r.append(fromColumn);
    r.append(" TO ");
    r.append(col.getColumnName());
    stmt.execute(r.toString());
  }

  @Override
  public boolean isStatementDelimiterSupported() {
    return false;
  }
}
