/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018, Regents of the University of California.
 *
 * This file is part of NDNS (Named Data Networking Domain Name Service).
 * See AUTHORS.md for complete list of NDNS authors and contributors.
 *
 * NDNS is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "db-mgr.hpp"
#include "logger.hpp"
#include "clients/response.hpp"

#include <iostream>
#include <fstream>

namespace ndn {
namespace ndns {

NDNS_LOG_INIT(DbMgr);

static const std::string NDNS_SCHEMA = R"VALUE(
CREATE TABLE IF NOT EXISTS zones (
  id    INTEGER NOT NULL PRIMARY KEY,
  name  blob NOT NULL UNIQUE,
  ttl   integer(10) NOT NULL);

CREATE TABLE IF NOT EXISTS zone_info (
  zone_id  INTEGER NOT NULL,
  key      VARCHAR(10) NOT NULL,
  value    blob NOT NULL,
  PRIMARY KEY (zone_id, key),
  FOREIGN KEY(zone_id) REFERENCES zones(id) ON UPDATE Cascade ON DELETE Cascade);

CREATE TABLE IF NOT EXISTS rrsets (
  id      INTEGER NOT NULL PRIMARY KEY,
  zone_id integer(10) NOT NULL,
  label   blob NOT NULL,
  type    blob NOT NULL,
  version blob NOT NULL,
  ttl     integer(10) NOT NULL,
  data    blob NOT NULL,
  FOREIGN KEY(zone_id) REFERENCES zones(id) ON UPDATE Cascade ON DELETE Cascade);

CREATE UNIQUE INDEX rrsets_zone_id_label_type_version
  ON rrsets (zone_id, label, type, version);
)VALUE";

DbMgr::DbMgr(const std::string& dbFile/* = DEFAULT_CONFIG_PATH "/" "ndns.db"*/)
  : m_dbFile(dbFile)
  , m_conn(0)
{
  if (dbFile.empty())
    m_dbFile = DEFAULT_DATABASE_PATH "/" "ndns.db";

  this->open();

  NDNS_LOG_INFO("open database: " << m_dbFile);
}


DbMgr::~DbMgr()
{
  if (m_conn != 0) {
    this->close();
  }
}

void
DbMgr::open()
{
  int res = sqlite3_open_v2(m_dbFile.c_str(), &m_conn,
                            SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
#ifdef DISABLE_SQLITE3_FS_LOCKING
                            "unix-dotfile"
#else
                            0
#endif
                            );

  if (res != SQLITE_OK) {
    NDNS_LOG_FATAL("Cannot open the db file: " << m_dbFile);
    BOOST_THROW_EXCEPTION(ConnectError("Cannot open the db file: " + m_dbFile));
  }
  // ignore any errors from DB creation (command will fail for the existing database, which is ok)
  sqlite3_exec(m_conn, NDNS_SCHEMA.c_str(), 0, 0, 0);
}

void
DbMgr::close()
{
  if (m_conn == 0)
    return;

  int ret = sqlite3_close(m_conn);
  if (ret != SQLITE_OK) {
    NDNS_LOG_FATAL("Cannot close the db: " << m_dbFile);
  }
  else {
    m_conn = 0;
    NDNS_LOG_INFO("Close database: " << m_dbFile);
  }
}

void
DbMgr::clearAllData()
{
  const char* sql = "DELETE FROM zones; DELETE FROM rrsets;";

  int rc = sqlite3_exec(m_conn, sql, 0, 0, 0); // sqlite3_step cannot execute multiple SQL statement
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(ExecuteError(sql));
  }

  NDNS_LOG_INFO("clear all the data in the database: " << m_dbFile);
}


void
DbMgr::saveName(const Name& name, sqlite3_stmt* stmt, int iCol, bool isStatic)
{
  const Block& wire = name.wireEncode();
  sqlite3_bind_blob(stmt, iCol, wire.value(), wire.value_size(), isStatic ? SQLITE_STATIC : SQLITE_TRANSIENT);
}

Name
DbMgr::restoreName(sqlite3_stmt* stmt, int iCol)
{
  Name name;

  const uint8_t* buffer = static_cast<const uint8_t*>(sqlite3_column_blob(stmt, iCol));
  size_t nBytesLeft = sqlite3_column_bytes(stmt, iCol);

  while (nBytesLeft > 0) {
    bool hasDecodingSucceeded;
    name::Component component;
    std::tie(hasDecodingSucceeded, component) = Block::fromBuffer(buffer, nBytesLeft);
    if (!hasDecodingSucceeded) {
      BOOST_THROW_EXCEPTION(Error("Error while decoding name from the database"));
    }
    name.append(component);
    buffer += component.size();
    nBytesLeft -= component.size();
  }

  return name;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// Zone
///////////////////////////////////////////////////////////////////////////////////////////////////

void
DbMgr::insert(Zone& zone)
{
  if (zone.getId() > 0)
    return;

  sqlite3_stmt* stmt;
  const char* sql = "INSERT INTO zones (name, ttl) VALUES (?, ?)";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }


  saveName(zone.getName(), stmt, 1);
  sqlite3_bind_int(stmt,  2, zone.getTtl().count());

  rc = sqlite3_step(stmt);
  if (rc != SQLITE_DONE) {
    sqlite3_finalize(stmt);
    BOOST_THROW_EXCEPTION(ExecuteError(sql));
  }

  zone.setId(sqlite3_last_insert_rowid(m_conn));
  sqlite3_finalize(stmt);
}

void
DbMgr::setZoneInfo(Zone& zone,
                   const std::string& key,
                   const Block& value)
{
  if (zone.getId() == 0) {
    BOOST_THROW_EXCEPTION(Error("zone has not been initialized"));
  }

  if (key.length() > 10) {
    BOOST_THROW_EXCEPTION(Error("key length should not exceed 10"));
  }

  sqlite3_stmt* stmt;
  const char* sql = "INSERT OR REPLACE INTO zone_info (zone_id, key, value) VALUES (?, ?, ?)";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int(stmt,  1, zone.getId());
  sqlite3_bind_text(stmt, 2, key.c_str(),  key.length(), SQLITE_STATIC);
  sqlite3_bind_blob(stmt, 3, value.wire(), value.size(), SQLITE_STATIC);

  rc = sqlite3_step(stmt);
  if (rc != SQLITE_DONE) {
    sqlite3_finalize(stmt);
    BOOST_THROW_EXCEPTION(ExecuteError(sql));
  }

  sqlite3_finalize(stmt);
}

std::map<std::string, Block>
DbMgr::getZoneInfo(Zone& zone)
{
  using std::string;
  std::map<string, Block> rtn;

  if (zone.getId() == 0) {
    find(zone);
  }

  if (zone.getId() == 0) {
    BOOST_THROW_EXCEPTION(Error("zone has not been initialized"));
  }

  sqlite3_stmt* stmt;
  const char* sql = "SELECT key, value FROM zone_info WHERE zone_id=?";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int(stmt, 1, zone.getId());

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    const char* key = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
    rtn[string(key)] = Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 1)),
                             sqlite3_column_bytes(stmt, 1));
  }

  sqlite3_finalize(stmt);
  return rtn;
}


bool
DbMgr::find(Zone& zone)
{
  sqlite3_stmt* stmt;
  const char* sql = "SELECT id, ttl FROM zones WHERE name=?";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  saveName(zone.getName(), stmt, 1);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    zone.setId(sqlite3_column_int64(stmt, 0));
    zone.setTtl(time::seconds(sqlite3_column_int(stmt, 1)));
  }
  else {
    zone.setId(0);
  }

  sqlite3_finalize(stmt);

  return zone.getId() != 0;
}

std::vector<Zone>
DbMgr::listZones()
{
  sqlite3_stmt* stmt;
  const char* sql = "SELECT id, name, ttl FROM zones";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  std::vector<Zone> vec;

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    vec.emplace_back();
    Zone& zone = vec.back();
    zone.setId(sqlite3_column_int64(stmt, 0));
    zone.setTtl(time::seconds(sqlite3_column_int(stmt, 2)));
    zone.setName(restoreName(stmt, 1));
  }
  sqlite3_finalize(stmt);

  return vec;
}

void
DbMgr::remove(Zone& zone)
{
  if (zone.getId() == 0)
    return;

  sqlite3_stmt* stmt;
  const char* sql = "DELETE FROM zones where id=?";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int64(stmt, 1, zone.getId());

  rc = sqlite3_step(stmt);
  if (rc != SQLITE_DONE) {
    sqlite3_finalize(stmt);
    BOOST_THROW_EXCEPTION(ExecuteError(sql));
  }

  sqlite3_finalize(stmt);

  zone = Zone();
}


///////////////////////////////////////////////////////////////////////////////////////////////////
// Rrset
///////////////////////////////////////////////////////////////////////////////////////////////////

void
DbMgr::insert(Rrset& rrset)
{
  if (rrset.getId() != 0)
    return;

  if (rrset.getZone() == 0) {
    BOOST_THROW_EXCEPTION(RrsetError("Rrset has not been assigned to a zone"));
  }

  if (rrset.getZone()->getId() == 0) {
    insert(*rrset.getZone());
  }

  const char* sql =
    "INSERT INTO rrsets (zone_id, label, type, version, ttl, data)"
    "    VALUES (?, ?, ?, ?, ?, ?)";

  sqlite3_stmt* stmt;
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int64(stmt, 1, rrset.getZone()->getId());

  saveName(rrset.getLabel(), stmt, 2);
  sqlite3_bind_blob(stmt,  3, rrset.getType().wire(),    rrset.getType().size(),    SQLITE_STATIC);
  sqlite3_bind_blob(stmt,  4, rrset.getVersion().wire(), rrset.getVersion().size(), SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 5, rrset.getTtl().count());
  sqlite3_bind_blob(stmt,  6, rrset.getData().wire(),    rrset.getData().size(),    SQLITE_STATIC);

  rc = sqlite3_step(stmt);
  if (rc != SQLITE_DONE) {
    sqlite3_finalize(stmt);
    BOOST_THROW_EXCEPTION(ExecuteError(sql));
  }

  rrset.setId(sqlite3_last_insert_rowid(m_conn));
  sqlite3_finalize(stmt);
}

bool
DbMgr::find(Rrset& rrset)
{
  if (rrset.getZone() == 0) {
    BOOST_THROW_EXCEPTION(RrsetError("Rrset has not been assigned to a zone"));
  }

  if (rrset.getZone()->getId() == 0) {
    bool isFound = find(*rrset.getZone());
    if (!isFound) {
      return false;
    }
  }

  sqlite3_stmt* stmt;
  const char* sql =
    "SELECT id, ttl, version, data FROM rrsets"
    "    WHERE zone_id=? and label=? and type=?";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);

  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int64(stmt, 1, rrset.getZone()->getId());

  saveName(rrset.getLabel(), stmt, 2);
  sqlite3_bind_blob(stmt, 3, rrset.getType().wire(), rrset.getType().size(), SQLITE_STATIC);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    rrset.setId(sqlite3_column_int64(stmt, 0));
    rrset.setTtl(time::seconds(sqlite3_column_int64(stmt, 1)));
    rrset.setVersion(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 2)),
                           sqlite3_column_bytes(stmt, 2)));
    rrset.setData(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 3)),
                        sqlite3_column_bytes(stmt, 3)));
  }
  else {
    rrset.setId(0);
  }
  sqlite3_finalize(stmt);

  return rrset.getId() != 0;
}

bool
DbMgr::findLowerBound(Rrset& rrset)
{
  if (rrset.getZone() == 0) {
    BOOST_THROW_EXCEPTION(RrsetError("Rrset has not been assigned to a zone"));
  }

  if (rrset.getZone()->getId() == 0) {
    bool isFound = find(*rrset.getZone());
    if (!isFound) {
      return false;
    }
  }

  sqlite3_stmt* stmt;
  const char* sql =
    "SELECT id, ttl, version, data FROM rrsets"
    "    WHERE zone_id=? and label<? and type=? ORDER BY label DESC";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);

  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int64(stmt, 1, rrset.getZone()->getId());

  saveName(rrset.getLabel(), stmt, 2);
  sqlite3_bind_blob(stmt, 3, rrset.getType().wire(), rrset.getType().size(), SQLITE_STATIC);

  if (sqlite3_step(stmt) == SQLITE_ROW) {
    rrset.setId(sqlite3_column_int64(stmt, 0));
    rrset.setTtl(time::seconds(sqlite3_column_int64(stmt, 1)));
    rrset.setVersion(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 2)),
                           sqlite3_column_bytes(stmt, 2)));
    rrset.setData(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 3)),
                        sqlite3_column_bytes(stmt, 3)));
  }
  else {
    rrset.setId(0);
  }
  sqlite3_finalize(stmt);

  return rrset.getId() != 0;
}

std::vector<Rrset>
DbMgr::findRrsets(Zone& zone)
{
  if (zone.getId() == 0)
    find(zone);

  if (zone.getId() == 0)
    BOOST_THROW_EXCEPTION(RrsetError("Attempting to find all the rrsets with a zone does not in the database"));

  std::vector<Rrset> vec;
  sqlite3_stmt* stmt;
  const char* sql = "SELECT id, ttl, version, data, label, type "
                    "FROM rrsets where zone_id=? ORDER BY label";

  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }
  sqlite3_bind_int64(stmt, 1, zone.getId());

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    vec.emplace_back(&zone);
    Rrset& rrset = vec.back();

    rrset.setId(sqlite3_column_int64(stmt, 0));
    rrset.setTtl(time::seconds(sqlite3_column_int64(stmt, 1)));
    rrset.setVersion(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 2)),
                           sqlite3_column_bytes(stmt, 2)));
    rrset.setData(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 3)),
                        sqlite3_column_bytes(stmt, 3)));
    rrset.setLabel(restoreName(stmt, 4));
    rrset.setType(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 5)),
                  sqlite3_column_bytes(stmt, 5)));
  }
  sqlite3_finalize(stmt);

  return vec;
}

void
DbMgr::removeRrsetsOfZoneByType(Zone& zone, const name::Component& type)
{
  if (zone.getId() == 0)
    find(zone);

  if (zone.getId() == 0)
    BOOST_THROW_EXCEPTION(RrsetError("Attempting to find all the rrsets with a zone does not in the database"));

  sqlite3_stmt* stmt;
  const char* sql = "DELETE FROM rrsets WHERE zone_id = ? AND type = ?";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);

  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int64(stmt, 1, zone.getId());
  sqlite3_bind_blob(stmt,  2, type.wire(), type.size(), SQLITE_STATIC);

  rc = sqlite3_step(stmt);
  if (rc != SQLITE_DONE) {
    sqlite3_finalize(stmt);
    BOOST_THROW_EXCEPTION(ExecuteError(sql));
  }
  sqlite3_finalize(stmt);
}

void
DbMgr::remove(Rrset& rrset)
{
  if (rrset.getId() == 0)
    BOOST_THROW_EXCEPTION(RrsetError("Attempting to remove Rrset that has no assigned id"));

  sqlite3_stmt* stmt;
  const char* sql = "DELETE FROM rrsets WHERE id=?";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);

  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int64(stmt, 1, rrset.getId());

  rc = sqlite3_step(stmt);
  if (rc != SQLITE_DONE) {
    sqlite3_finalize(stmt);
    BOOST_THROW_EXCEPTION(ExecuteError(sql));
  }

  sqlite3_finalize(stmt);

  rrset = Rrset(rrset.getZone());
}

void
DbMgr::update(Rrset& rrset)
{
  if (rrset.getId() == 0) {
    BOOST_THROW_EXCEPTION(RrsetError("Attempting to replace Rrset that has no assigned id"));
  }

  if (rrset.getZone() == 0) {
    BOOST_THROW_EXCEPTION(RrsetError("Rrset has not been assigned to a zone"));
  }

  sqlite3_stmt* stmt;
  const char* sql = "UPDATE rrsets SET ttl=?, version=?, data=? WHERE id=?";
  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);

  if (rc != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(PrepareError(sql));
  }

  sqlite3_bind_int64(stmt, 1, rrset.getTtl().count());
  sqlite3_bind_blob(stmt,  2, rrset.getVersion().wire(), rrset.getVersion().size(), SQLITE_STATIC);
  sqlite3_bind_blob(stmt,  3, rrset.getData().wire(),    rrset.getData().size(),    SQLITE_STATIC);
  sqlite3_bind_int64(stmt, 4, rrset.getId());

  sqlite3_step(stmt);
  sqlite3_finalize(stmt);
}

} // namespace ndns
} // namespace ndn
