/**
 * 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.
 */

#ifndef NIFI_MINIFI_CPP_SQLITECONNECTION_H
#define NIFI_MINIFI_CPP_SQLITECONNECTION_H

#include <sqlite3.h>

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace sqlite {

class SQLiteConnection;

/**
 * RAII wrapper for a sqlite3 prepared statement
 */
class SQLiteStatement {
 public:
  SQLiteStatement(sqlite3 *db, const std::string &sql)
      : logger_(logging::LoggerFactory<SQLiteConnection>::getLogger()) {
    if (sqlite3_prepare_v3(db, sql.c_str(), sql.size(), 0, &stmt_, nullptr)) {
      std::stringstream err_msg;
      err_msg << "Failed to create prepared statement: ";
      err_msg << sql;
      err_msg << " because ";
      err_msg << sqlite3_errmsg(db);
      throw std::runtime_error(err_msg.str());
    }

    if (!stmt_) {
      std::stringstream err_msg;
      err_msg << "Failed to create prepared statement: ";
      err_msg << sql;
      err_msg << " because statement was NULL";
      throw std::runtime_error(err_msg.str());
    }

    db_ = db;
  }

  ~SQLiteStatement() {
    sqlite3_finalize(stmt_);
  }

  void bind_text(int pos, const std::string &text) {
    if (sqlite3_bind_text(stmt_, pos, text.c_str(), text.size(), SQLITE_TRANSIENT)) {
      std::stringstream err_msg;
      err_msg << "Failed to bind text parameter"
              << pos
              << ": "
              << text
              << " because "
              << sqlite3_errmsg(db_);
      throw std::runtime_error(err_msg.str());
    }
  }

  void bind_int64(int pos, uint64_t val) {
    if (sqlite3_bind_int64(stmt_, pos, val)) {
      std::stringstream err_msg;
      err_msg << "Failed to bind int64 parameter"
              << pos
              << ": "
              << val
              << " because "
              << sqlite3_errmsg(db_);
      throw std::runtime_error(err_msg.str());
    }
  }

  void bind_double(int pos, double val) {
    if (sqlite3_bind_double(stmt_, pos, val)) {
      std::stringstream err_msg;
      err_msg << "Failed to bind double parameter"
              << pos
              << ": "
              << val
              << " because "
              << sqlite3_errmsg(db_);
      throw std::runtime_error(err_msg.str());
    }
  }

  void bind_null(int pos) {
    if (sqlite3_bind_null(stmt_, pos)) {
      std::stringstream err_msg;
      err_msg << "Failed to bind NULL parameter"
              << pos
              << " because "
              << sqlite3_errmsg(db_);
      throw std::runtime_error(err_msg.str());
    }
  }

  void step() {
    int rc = sqlite3_step(stmt_);
    if (rc == SQLITE_BUSY) {
      reset_flags();
      is_ok_ = false;
      is_busy_ = true;
    } else if (rc == SQLITE_DONE) {
      reset_flags();
      is_done_ = true;
    } else if (rc == SQLITE_ROW) {
      reset_flags();
      is_row_ = true;
    } else {
      is_ok_ = false;
      is_error_ = true;
      std::stringstream err_msg;
      err_msg << "Failed to step statement because "
              << sqlite3_errmsg(db_);
      throw std::runtime_error(err_msg.str());
    }
  }

  bool is_ok() {
    return is_ok_;
  }

  bool is_done() {
    return is_done_;
  }

  bool is_row() {
    return is_row_;
  }

  bool is_error() {
    return is_error_;
  }

  bool is_busy() {
    return is_busy_;
  }

  std::string column_text(int col) {
    return std::string(reinterpret_cast<const char *>(sqlite3_column_text(stmt_, col)));
  }

  uint64_t  column_int64(int col) {
    return sqlite3_column_int64(stmt_, col);
  }

  double column_double(int col) {
    return sqlite3_column_double(stmt_, col);
  }

  bool column_is_int(int col) {
    return SQLITE_INTEGER == sqlite3_column_type(stmt_, col);
  }

  bool column_is_float(int col) {
    return SQLITE_FLOAT == sqlite3_column_type(stmt_, col);
  }

  bool column_is_text(int col) {
    return SQLITE_TEXT == sqlite3_column_type(stmt_, col);
  }

  bool column_is_blob(int col) {
    return SQLITE_BLOB == sqlite3_column_type(stmt_, col);
  }

  bool column_is_null(int col) {
    return SQLITE_NULL == sqlite3_column_type(stmt_, col);
  }

  std::string column_name(int col) {
    return std::string(sqlite3_column_name(stmt_, col));
  }

  int column_count() {
    return sqlite3_column_count(stmt_);
  }

  void reset() {
    sqlite3_reset(stmt_);
  }

 private:
  std::shared_ptr<logging::Logger> logger_;

  sqlite3_stmt *stmt_;
  sqlite3 *db_ = nullptr;
  bool is_ok_ = true;
  bool is_busy_ = false;
  bool is_done_ = false;
  bool is_error_ = false;
  bool is_row_ = false;

  void reset_flags() {
    is_ok_ = true;
    is_busy_ = false;
    is_done_ = false;
    is_error_ = false;
    is_row_ = false;
  }
};

/**
 * RAII wrapper for a sqlite3 connection
 */
class SQLiteConnection {
 public:
  SQLiteConnection(const std::string &filename)
      : logger_(logging::LoggerFactory<SQLiteConnection>::getLogger()),
        filename_(filename) {
    logger_->log_info("Opening SQLite database: %s", filename_);

    if (sqlite3_open(filename_.c_str(), &db_)) {
      std::stringstream err_msg("Failed to open database: ");
      err_msg << filename_;
      err_msg << " because ";
      err_msg << sqlite3_errmsg(db_);
      throw std::runtime_error(err_msg.str());
    }
  }

  SQLiteConnection(SQLiteConnection &&other)
      : logger_(std::move(other.logger_)),
        filename_(std::move(other.filename_)),
        db_(other.db_) {
    other.db_ = nullptr;
  }

  ~SQLiteConnection() {
    logger_->log_info("Closing SQLite database: %s", filename_);
    sqlite3_close(db_);
  }

  SQLiteStatement prepare(const std::string sql) {
    return SQLiteStatement(db_, sql);
  }

  std::string errormsg() {
    return sqlite3_errmsg(db_);
  }

 private:
  std::shared_ptr<logging::Logger> logger_;
  std::string filename_;

  sqlite3 *db_ = nullptr;
};

} /* namespace sqlite */
} /* namespace minifi */
} /* namespace nifi */
} /* namespace apache */
} /* namespace org */

#endif //NIFI_MINIFI_CPP_SQLITECONNECTION_H
