// Copyright 2009 Google Inc.
//
// 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.client.Column;
import com.google.gwtorm.schema.ColumnModel;
import com.google.gwtorm.schema.SequenceModel;
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.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.HashSet;
import java.util.Set;

/** Dialect for <a href="http://www.mysql.com/">MySQL</a> */
public class DialectMySQL extends SqlDialect {
  public DialectMySQL() {
    types.put(String.class, new SqlStringTypeInfo() {
      @Override
      public String getSqlType(final ColumnModel col, final SqlDialect dialect) {
        final Column column = col.getColumnAnnotation();
        final StringBuilder r = new StringBuilder();

        if (column.length() <= 0) {
          r.append("VARCHAR(255) BINARY");
          if (col.isNotNull()) {
            r.append(" DEFAULT ''");
          }
        } else if (column.length() <= 255) {
          r.append("VARCHAR(" + column.length() + ") BINARY");
          if (col.isNotNull()) {
            r.append(" DEFAULT ''");
          }
        } else {
          r.append(dialect.getSqlTypeName(Types.LONGVARCHAR));
        }

        if (col.isNotNull()) {
          r.append(" NOT NULL");
        }

        return r.toString();
      }
    });
    types.put(Timestamp.class, new SqlTimestampTypeInfo() {
      @Override
      public String getSqlType(ColumnModel col, SqlDialect dialect) {
        final StringBuilder r = new StringBuilder();
        r.append(dialect.getSqlTypeName(getSqlTypeConstant()));
        if (col.isNotNull()) {
          r.append(" NOT NULL");
        } else {
          r.append(" NULL DEFAULT NULL");
        }
        return r.toString();
      }
    });
  }

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

  @Override
  public String getCreateSequenceSql(final SequenceModel seq) {
    final StringBuilder r = new StringBuilder();
    r.append("CREATE TABLE ");
    r.append(seq.getSequenceName());
    r.append("(s SERIAL)");
    return r.toString();
  }

  @Override
  public String getDropSequenceSql(String name) {
    return "DROP TABLE " + name;
  }

  @Override
  protected String getDropIndexSql(String tableName, String name) {
    return "DROP INDEX " + name + " ON " + tableName;
  }

  @Override
  protected String getNextSequenceValueSql(final String seqname) {
    return seqname;
  }

  @Override
  public long nextLong(final Connection conn, final String seqname)
      throws OrmException {
    try {
      final Statement st = conn.createStatement();
      try {
        st.execute("INSERT INTO " + seqname + "(s)VALUES(NULL)",
            Statement.RETURN_GENERATED_KEYS);
        final long r;
        final ResultSet rs = st.getGeneratedKeys();
        try {
          if (!rs.next()) {
            throw new SQLException("No result row for sequence query");
          }
          r = rs.getLong(1);
        } finally {
          rs.close();
        }
        return r;
      } finally {
        st.close();
      }
    } catch (SQLException e) {
      throw convertError("sequence", seqname, e);
    }
  }

  @Override
  public Set<String> listTables(final Connection db) throws SQLException {
    final String[] types = new String[] {"TABLE"};
    final ResultSet rs = db.getMetaData().getTables(null, null, null, types);
    try {
      HashSet<String> tables = new HashSet<>();
      while (rs.next()) {
        final String name = rs.getString("TABLE_NAME");
        if (!isSequence(db, name)) {
          tables.add(name.toLowerCase());
        }
      }
      return tables;
    } finally {
      rs.close();
    }
  }

  @Override
  public Set<String> listSequences(final Connection db) throws SQLException {
    final String[] types = new String[] {"TABLE"};
    final ResultSet rs = db.getMetaData().getTables(null, null, null, types);
    try {
      HashSet<String> sequences = new HashSet<>();
      while (rs.next()) {
        final String name = rs.getString("TABLE_NAME");
        if (isSequence(db, name)) {
          sequences.add(name.toLowerCase());
        }
      }
      return sequences;
    } finally {
      rs.close();
    }
  }

  private boolean isSequence(Connection db, String tableName)
      throws SQLException {
    final DatabaseMetaData meta = db.getMetaData();
    if (meta.storesUpperCaseIdentifiers()) {
      tableName = tableName.toUpperCase();
    } else if (meta.storesLowerCaseIdentifiers()) {
      tableName = tableName.toLowerCase();
    }

    ResultSet rs = meta.getColumns(null, null, tableName, null);
    try {
      int cnt = 0;
      boolean serial = false;
      while (rs.next()) {
        cnt++;
        if (rs.getInt("DATA_TYPE") == Types.BIGINT
            && "YES".equalsIgnoreCase(rs.getString("IS_AUTOINCREMENT"))) {
          serial = true;
        }
      }
      return cnt == 1 && serial;
    } finally {
      rs.close();
    }
  }

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

  @Override
  public void renameColumn(StatementExecutor stmt, String tableName,
      String fromColumn, ColumnModel col) throws OrmException {
    StringBuffer r = new StringBuffer();
    r.append("ALTER TABLE ");
    r.append(tableName);
    r.append(" CHANGE ");
    r.append(fromColumn);
    r.append(" ");
    r.append(col.getColumnName());
    r.append(" ");
    r.append(getSqlTypeInfo(col).getSqlType(col, this));
    stmt.execute(r.toString());
  }

  @Override
  public OrmException convertError(String op, String entity, SQLException err) {
    switch (err.getErrorCode()) {
      case 1022: // ER_DUP_KEY
      case 1062: // ER_DUP_ENTRY
      case 1169: // ER_DUP_UNIQUE;
        return new OrmDuplicateKeyException(entity, err);
      default:
        return super.convertError(op, entity, err);
    }
  }
}
