#include <cinttypes>

const char create_like_table[] = "CREATE TABLE IF NOT EXISTS like_table ( ID INTEGER PRIMARY KEY, USER_TABLE_ID INTEGER, HASH INTEGER, POS INTEGER, LIKED INTEGER);";

const char create_user_table[] = "CREATE TABLE IF NOT EXISTS user_table ( ID INTEGER PRIMARY KEY, USER_ID INTEGER, GEN INTEGER, CHECKED INTEGER);";

const char max_gen[] = "SELECT MAX(GEN) FROM user_table WHERE USER_ID = ?;";

const char insert_user_data[] = "INSERT INTO user_table (USER_ID, GEN, CHECKED) VALUES(?, ?, 0);";

const char insert_like_data[] = "INSERT INTO like_table (USER_TABLE_ID, HASH, POS, LIKED) VALUES(?, ?, ?, ?);";

const char get_unchecked[] = "SELECT USER_ID FROM user_table WHERE CHECKED = 0;";

const char get_gen[] = "SELECT lt.HASH, lt.POS, lt.LIKED FROM like_table lt JOIN user_table ut ON lt.USER_TABLE_ID = ut.ID WHERE ut.USER_ID = ? AND ut.GEN = ? ORDER BY lt.POS ASC;";

const char get_user_table_id[] = "SELECT ID FROM user_table WHERE USER_ID = ? AND GEN >= ?;";

const char rem_like_w_user_table_id[] = "DELETE FROM like_table WHERE USER_TABLE_ID = ?;";

const char rem_user_table_id[] = "DELETE FROM user_table WHERE ID = ?;";

const char set_checked[] = "UPDATE user_table SET CHECKED = 1 WHERE USER_ID = ? AND GEN = ?;";

constexpr char DB_NAME[] = "data.db";

struct sqlite3;
struct sqlite3_stmt;

#define SQL_DONE 101
#define SQL_NULL 5

namespace sql
{
  void create_tables();
  void init();
  void shutdown();
  int open(const char *filename, sqlite3 **ppDb);
  int prepare_v2(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **pStmt, const char **pzTail);
  int bind_int64(sqlite3_stmt *pStmt, int column, int64_t value);
  int step(sqlite3_stmt *pStmt);
  int column_count(sqlite3_stmt *pStmt);
  int column_type(sqlite3_stmt *pStmt, int column);
  int64_t column_int64(sqlite3_stmt *pStmt, int column);
  int finalize(sqlite3_stmt *pStmt);
  int reset(sqlite3_stmt *pStmt);
  int close(sqlite3 *db);
  const char *errmsg(sqlite3 *db);
  int64_t last_insert_rowid(sqlite3 *db);
}