/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2015,  Regents of the University of California
 *
 * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
 * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
 *
 * ndn-group-encrypt 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.
 *
 * ndn-group-encrypt 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
 * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
 */

#include "group-manager-db.hpp"

#include <sqlite3.h>
#include <boost/filesystem.hpp>
#include <ndn-cxx/util/sqlite3-statement.hpp>
#include <ndn-cxx/security/identity-certificate.hpp>

namespace ndn {
namespace gep {

using util::Sqlite3Statement;

static const std::string INITIALIZATION =
  "CREATE TABLE IF NOT EXISTS                         \n"
  "  schedules(                                       \n"
  "    schedule_id         INTEGER PRIMARY KEY,       \n"
  "    schedule_name       TEXT NOT NULL,             \n"
  "    schedule            BLOB NOT NULL              \n"
  "  );                                               \n"
  "CREATE UNIQUE INDEX IF NOT EXISTS                  \n"
  "   scheduleNameIndex ON schedules(schedule_name);  \n"
  "                                                   \n"
  "CREATE TABLE IF NOT EXISTS                         \n"
  "  members(                                         \n"
  "    member_id           INTEGER PRIMARY KEY,       \n"
  "    schedule_id         INTEGER NOT NULL,          \n"
  "    member_name         BLOB NOT NULL,             \n"
  "    member_cert         BLOB NOT NULL,             \n"
  "    FOREIGN KEY(schedule_id)                       \n"
  "      REFERENCES schedules(schedule_id)            \n"
  "      ON DELETE CASCADE                            \n"
  "      ON UPDATE CASCADE                            \n"
  "  );                                               \n"
  "CREATE UNIQUE INDEX IF NOT EXISTS                  \n"
  "   memNameIndex ON members(member_name);           \n";

class GroupManagerDB::Impl
{
public:
  Impl(const std::string& dbDir)
  {
    // open Database

    int result = sqlite3_open_v2(dbDir.c_str(), &m_database,
                                 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
                                 "unix-dotfile"
#else
                                 nullptr
#endif
                                 );

    if (result != SQLITE_OK)
      BOOST_THROW_EXCEPTION(Error("GroupManager DB cannot be opened/created: " + dbDir));

    // enable foreign key
    sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);

    // initialize database specific tables
    char* errorMessage = nullptr;
    result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
    if (result != SQLITE_OK && errorMessage != nullptr) {
      sqlite3_free(errorMessage);
      BOOST_THROW_EXCEPTION(Error("GroupManager DB cannot be initialized"));
    }
  }

  ~Impl()
  {
    sqlite3_close(m_database);
  }

  int
  getScheduleId(const std::string& name) const
  {
    Sqlite3Statement statement(m_database,
                               "SELECT schedule_id FROM schedules WHERE schedule_name=?");
    statement.bind(1, name, SQLITE_TRANSIENT);

    int result = -1;
    if (statement.step() == SQLITE_ROW)
      result = statement.getInt(0);
    return result;
  }

public:
  sqlite3* m_database;
};

GroupManagerDB::GroupManagerDB(const std::string& dbDir)
  : m_impl(new Impl(dbDir))
{
}

GroupManagerDB::~GroupManagerDB() = default;

bool
GroupManagerDB::hasSchedule(const std::string& name) const
{
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT schedule_id FROM schedules where schedule_name=?");
  statement.bind(1, name, SQLITE_TRANSIENT);
  return (statement.step() == SQLITE_ROW);
}

std::list<std::string>
GroupManagerDB::listAllScheduleNames() const
{
  std::list<std::string> result;
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT schedule_name FROM schedules");

  result.clear();
  while (statement.step() == SQLITE_ROW) {
    result.push_back(statement.getString(0));
  }
  return result;
}

Schedule
GroupManagerDB::getSchedule(const std::string& name) const
{
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT schedule FROM schedules where schedule_name=?");
  statement.bind(1, name, SQLITE_TRANSIENT);

  Schedule result;
  if (statement.step() == SQLITE_ROW) {
    result.wireDecode(statement.getBlock(0));
  }
  else {
    BOOST_THROW_EXCEPTION(Error("Cannot get the result from database"));
  }
  return result;
}

std::map<Name, Data>
GroupManagerDB::getScheduleMembers(const std::string& name) const
{
  std::map<Name, Data> result;
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT member_name, member_cert\
                              FROM members JOIN schedules\
                              ON members.schedule_id=schedules.schedule_id\
                              WHERE schedule_name=?");
  statement.bind(1, name, SQLITE_TRANSIENT);

  result.clear();
  while (statement.step() == SQLITE_ROW) {
    result.insert(std::pair<Name, Data>(Name(statement.getBlock(0)),
                                        Data(statement.getBlock(1))));
  }
  return result;
}

void
GroupManagerDB::addSchedule(const std::string& name, const Schedule& schedule)
{
  BOOST_ASSERT(name.length() != 0);

  Sqlite3Statement statement(m_impl->m_database,
                             "INSERT INTO schedules (schedule_name, schedule)\
                              values (?, ?)");
  statement.bind(1, name, SQLITE_TRANSIENT);
  statement.bind(2, schedule.wireEncode(), SQLITE_TRANSIENT);
  if (statement.step() != SQLITE_DONE)
    BOOST_THROW_EXCEPTION(Error("Cannot add the schedule to database"));
}

void
GroupManagerDB::deleteSchedule(const std::string& name)
{
  Sqlite3Statement statement(m_impl->m_database,
                             "DELETE FROM schedules WHERE schedule_name=?");
  statement.bind(1, name, SQLITE_TRANSIENT);
  statement.step();
}

void
GroupManagerDB::renameSchedule(const std::string& oldName, const std::string& newName)
{
  BOOST_ASSERT(newName.length() != 0);

  Sqlite3Statement statement(m_impl->m_database,
                             "UPDATE schedules SET schedule_name=? WHERE schedule_name=?");
  statement.bind(1, newName, SQLITE_TRANSIENT);
  statement.bind(2, oldName, SQLITE_TRANSIENT);
  if (statement.step() != SQLITE_DONE)
    BOOST_THROW_EXCEPTION(Error("Cannot rename the schedule from database"));
}

void
GroupManagerDB::updateSchedule(const std::string& name, const Schedule& schedule)
{
  if (!hasSchedule(name)) {
    addSchedule(name, schedule);
    return;
  }

  Sqlite3Statement statement(m_impl->m_database,
                             "UPDATE schedules SET schedule=? WHERE schedule_name=?");
  statement.bind(1, schedule.wireEncode(), SQLITE_TRANSIENT);
  statement.bind(2, name, SQLITE_TRANSIENT);
  statement.step();
}

bool
GroupManagerDB::hasMember(const Name& identity) const
{
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT member_id FROM members WHERE member_name=?");
  statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
  return (statement.step() == SQLITE_ROW);
}

std::list<Name>
GroupManagerDB::listAllMembers() const
{
  std::list<Name> result;
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT member_name FROM members");

  result.clear();
  while (statement.step() == SQLITE_ROW) {
    result.push_back(Name(statement.getBlock(0)));
  }
  return result;
}

Data
GroupManagerDB::getMemberCert(const Name& identity) const
{
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT member_cert FROM members WHERE member_name=?");
  statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
  Data result;
  if (statement.step() == SQLITE_ROW) {
    result.wireDecode(statement.getBlock(0));
  }
  else {
    BOOST_THROW_EXCEPTION(Error("Cannot get the result from database"));
  }
  return result;
}

std::string
GroupManagerDB::getMemberSchedule(const Name& identity) const
{
  Sqlite3Statement statement(m_impl->m_database,
                             "SELECT schedule_name\
                              FROM schedules JOIN members\
                              ON schedules.schedule_id = members.schedule_id\
                              WHERE member_name=?");
  statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);

  std::string result = "";
  if (statement.step() == SQLITE_ROW) {
    result = statement.getString(0);
  }
  else {
    BOOST_THROW_EXCEPTION(Error("Cannot get the result from database"));
  }
  return result;
}

void
GroupManagerDB::addMember(const std::string& scheduleName, const Data& certificate)
{
  int scheduleId = m_impl->getScheduleId(scheduleName);
  if (scheduleId == -1)
    BOOST_THROW_EXCEPTION(Error("The schedule dose not exist"));

  IdentityCertificate cert(certificate);
  Name memberName = cert.getPublicKeyName().getPrefix(-1);

  Sqlite3Statement statement(m_impl->m_database,
                             "INSERT INTO members(schedule_id, member_name, member_cert)\
                              values (?, ?, ?)");
  statement.bind(1, scheduleId);
  statement.bind(2, memberName.wireEncode(), SQLITE_TRANSIENT);
  statement.bind(3, certificate.wireEncode(), SQLITE_TRANSIENT);
  if (statement.step() != SQLITE_DONE)
    BOOST_THROW_EXCEPTION(Error("Cannot add the member to database"));
}

void
GroupManagerDB::updateMemberSchedule(const Name& identity, const std::string& scheduleName)
{
  int scheduleId = m_impl->getScheduleId(scheduleName);
  if (scheduleId == -1)
    BOOST_THROW_EXCEPTION(Error("The schedule dose not exist"));

  Sqlite3Statement statement(m_impl->m_database,
                             "UPDATE members SET schedule_id=? WHERE member_name=?");
  statement.bind(1, scheduleId);
  statement.bind(2, identity.wireEncode(), SQLITE_TRANSIENT);
  statement.step();
}

void
GroupManagerDB::deleteMember(const Name& identity)
{
  Sqlite3Statement statement(m_impl->m_database,
                             "DELETE FROM members WHERE member_name=?");
  statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
  statement.step();
}

} // namespace gep
} // namespace ndn
