/*
 * 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.knox.gateway.shell.jdbc.derby;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.knox.gateway.i18n.messages.MessageLevel;
import org.apache.knox.gateway.shell.jdbc.Database;

public class DerbyDatabase implements Database {

  public static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
  public static final String PROTOCOL = "jdbc:derby:";
  private static final String CREATE_ATTRIBUTE = ";create=true";
  private static final String SHUTDOWN_ATTRIBUTE = ";shutdown=true";

  private final String dbUri;

  /**
   * Constructor
   *
   * @param directory
   *          the directory where the database should be placed
   * @throws DerbyDatabaseException
   *           if the database engine can not be load for some reasons
   */
  public DerbyDatabase(String directory) throws DerbyDatabaseException {
    this.dbUri = PROTOCOL + directory;
    loadDriver();
  }

  @Override
  public void create() throws SQLException {
    Connection conn = null;
    try {
      conn = DriverManager.getConnection(dbUri + CREATE_ATTRIBUTE);
    } finally {
      if (conn != null) {
        conn.close();
      }
    }
  }

  @Override
  public void shutdown() {
    try {
      DriverManager.getConnection(dbUri + SHUTDOWN_ATTRIBUTE);
    } catch (SQLException e) {
      // See http://db.apache.org/derby/docs/dev/getstart/rwwdactivity3.html and check
      // out 'Shut down the database' for an
      // explanation of this check
      if (((e.getErrorCode() == 45000) && ("08006".equals(e.getSQLState())))) {
        // We got the expected exception
        // Note that for single database shutdown, the expected
        // SQL state is "08006", and the error code is 45000.
        log(MessageLevel.INFO, "Derby database is closed");
      } else {
        // if the error code or SQLState is different, we have
        // an unexpected exception (shutdown failed)
        log(MessageLevel.WARN, "Derby database closed abnormally", e);
      }
    }
  }

  @Override
  public Connection getConnection() throws SQLException {
    return DriverManager.getConnection(dbUri);
  }

  @Override
  public boolean hasTable(String tableName) throws SQLException {
    return hasTable(null, tableName);
  }

  @Override
  public boolean hasTable(String schemaName, String tableName) throws SQLException {
    boolean result = false;
    try (Connection connection = getConnection();
        ResultSet tables = connection.getMetaData().getTables(connection.getCatalog(), schemaName, tableName, null)) {
      result = tables.next();
    } catch (SQLException e) {
      log(MessageLevel.ERROR, "SQL error occured while checking table " + tableName + " in the database", e);
    }

    return result;
  }

  private void loadDriver() throws DerbyDatabaseException {
    try {
      Class.forName(DRIVER).newInstance();
    } catch (ClassNotFoundException e) {
      throw new DerbyDatabaseException("Unable to load the JDBC driver " + DRIVER + ". Check your CLASSPATH.", e);
    } catch (InstantiationException e) {
      throw new DerbyDatabaseException("Unable to instantiate the JDBC driver " + DRIVER, e);
    } catch (IllegalAccessException e) {
      throw new DerbyDatabaseException("Not allowed to access the JDBC driver " + DRIVER, e);
    }
  }

  private void log(MessageLevel logLevel, String message) {
    log(logLevel, message, null);
  }

  // being a test only class we now log into the STDOUT for now
  private void log(MessageLevel logLevel, String message, Throwable error) {
    System.out.println(logLevel.name() + " - " + message + (error == null ? "" : " - caused by " + error));
  }
}
