/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2019, 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/>.
 */

#ifndef NDNS_DAEMON_DB_MGR_HPP
#define NDNS_DAEMON_DB_MGR_HPP

#include "config.hpp"
#include "rrset.hpp"
#include "zone.hpp"

#include <map>
#include <sqlite3.h>

namespace ndn {
namespace ndns {

#define DEFINE_ERROR(ErrorName, Base)           \
class ErrorName : public Base                   \
{                                               \
public:                                         \
  explicit                                      \
  ErrorName(const std::string& what)            \
    : Base(what)                                \
  {                                             \
  }                                             \
}

/**
 * @brief Database Manager, provides CRUD operations on stored entities
 *
 * @note Method names follow MongoDB convention: insert/remove/find/update
 */
class DbMgr : noncopyable
{
public:
  /**
   * @brief The Database Status
   */
  enum DbStatus {
    DB_CONNECTED,
    DB_CLOSED,
    DB_ERROR
  };

  DEFINE_ERROR(Error, std::runtime_error);
  DEFINE_ERROR(PrepareError, Error);
  DEFINE_ERROR(ExecuteError, Error);
  DEFINE_ERROR(ConnectError, Error);

public:
  explicit
  DbMgr(const std::string& dbFile = DEFAULT_DATABASE_PATH "/" "ndns.db");

  ~DbMgr();

  /**
   * @brief connect to the database. If it's already opened, do nothing.
   */
  void
  open();

  /**
   * @brief close the database connection. Do nothing if it's already closed.
   * Destructor would automatically close the database connection as well.
   */
  void
  close();

  /**
  * @brief clear all the data in the database
  */
  void
  clearAllData();

public: // Zone manipulation
  DEFINE_ERROR(ZoneError, Error);

  /**
   * @brief insert the m_zone to the database, and set the zone's id.
   * If the zone is already in the db, handle the exception without leaving it to upper level,
   * meanwhile, set the zone's id too.
   * @pre m_zone.getId() == 0
   * @post m_zone.getId() > 0
   */
  void
  insert(Zone& zone);

  /**
   * @brief set zoneInfo by key-value
   */
  void
  setZoneInfo(Zone& zone,
              const std::string& key,
              const Block& value);

  /**
   * @brief get zoneInfo
   */
  std::map<std::string, Block>
  getZoneInfo(Zone& zone);

  /**
   * @brief lookup the zone by name, fill the m_id and m_ttl
   * @post whatever the previous id is
   * @return true if the record exist
   */
  bool
  find(Zone& zone);

  /**
   * @brief get all zones in the database
   */
  std::vector<Zone>
  listZones();

  /**
   * @brief remove the zone
   * @pre m_zone.getId() > 0
   * @post m_zone.getId() == 0
   */
  void
  remove(Zone& zone);

public: // Rrset manipulation
  DEFINE_ERROR(RrsetError, Error);

  /**
   * @brief add the rrset
   * @pre m_rrset.getId() == 0
   * @post m_rrset.getId() > 0
   */
  void
  insert(Rrset& rrset);

  /**
   * @brief get the data from db according to `m_zone`, `m_label`, `m_type`.
   *
   * If record exists, `m_ttl`, `m_version` and `m_data` is set
   *
   * @pre m_rrset.getZone().getId() > 0
   * @post whatever the previous id is,
   *       m_rrset.getId() > 0 if record exists, otherwise m_rrset.getId() == 0
   * @return true if the record exist
   */
  bool
  find(Rrset& rrset);

  /**
   * @brief get the data from db according to `m_zone`, `m_label`, `m_type`.
   *
   * The lower bound rrset is the largest label that is less than rrset's label
   * If record exists, `m_ttl`, `m_version` and `m_data` is set
   *
   * @pre m_rrset.getZone().getId() > 0
   * @post whatever the previous id is,
   *       m_rrset.getId() > 0 if record exists, otherwise m_rrset.getId() == 0
   * @return true if the record exist
   */
  bool
  findLowerBound(Rrset& rrset);

  /**
   * @brief get all the rrsets which is stored at given zone
   * @throw RrsetError() if zone does not exist in the database
   * @note if zone.getId() == 0, the function setId for the zone automatically
   * @note all returned rrsets' m_zone point to the memory of the param[in] zone
   */
  std::vector<Rrset>
  findRrsets(Zone& zone);

  /**
   * @brief remove the rrset
   * @pre m_rrset.getId() > 0
   * @post m_rrset.getId() == 0
   */
  void
  remove(Rrset& rrset);

  /**
   * @brief remove all records of a specific type in a zone
   */
  void
  removeRrsetsOfZoneByType(Zone& zone,
                           const name::Component& type);

  /**
   * @brief replace ttl, version, and Data with new values
   * @pre m_rrset.getId() > 0
   */
  void
  update(Rrset& rrset);

public:
  const std::string&
  getDbFile() const
  {
    return m_dbFile;
  }

private:
  /**
   * @brief Save @p name to the database in the internal sortable format
   *
   * If @p name is not preserved until @p stmt is executed, @p isStatic must be
   * set to `false`.
   */
  void
  saveName(const Name& name, sqlite3_stmt* stmt, int iCol, bool isStatic = true);

  Name
  restoreName(sqlite3_stmt* stmt, int iCol);

private:
  std::string m_dbFile;
  sqlite3* m_conn;
};

} // namespace ndns
} // namespace ndn

#endif // NDNS_DAEMON_DB_MGR_HPP
