/* -*- 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 NAC (Name-Based Access Control for NDN).
 * See AUTHORS.md for complete list of NAC authors and contributors.
 *
 * NAC 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.
 *
 * NAC 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
 * NAC, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Zhiyi Zhang <zhiyi@cs.ucla.edu>
 */

#ifndef GEP_GROUP_MANAGER_DB_HPP
#define GEP_GROUP_MANAGER_DB_HPP

#include "schedule.hpp"

namespace ndn {
namespace nac {

/**
 * @brief GroupManagerDB is a class to manage the database of group manager.
 *
 * It contains two tables to store Schedules and Members
 */
class GroupManagerDB
{
public:
  class Error : public std::runtime_error
  {
  public:
    using std::runtime_error::runtime_error;
  };

public:
  /**
   * @brief Create the database of group manager at path @p dbPath.
   */
  explicit
  GroupManagerDB(const std::string& dbPath);

  ~GroupManagerDB();

public:
  ////////////////////////////////////////////////////// schedule management

  /**
   * @brief Check if there is a schedule with @p name
   */
  bool
  hasSchedule(const std::string& name) const;

  /**
   * @brief List all the names of the schedules
   * @return A list of the name of all schedules.
   */
  std::list<std::string>
  listAllScheduleNames() const;

  /**
   * @brief Get a schedule with @p name.
   * @throw Error if the schedule does not exist
   */
  Schedule
  getSchedule(const std::string& name) const;

  /**
   * @brief Get member key name and public key buffer of a schedule with @p name.
   */
  std::map<Name, Buffer>
  getScheduleMembers(const std::string& name) const;

  /**
   * @brief Add a @p schedule with @p name
   * @pre Name.length() != 0
   *
   * @throw Error if add operation fails, e.g., a schedule with the same name already exists
   */
  void
  addSchedule(const std::string& name, const Schedule& schedule);

  /**
   * @brief Delete the schedule with @p name.
   *        also delete members which reference the schedule.
   */
  void
  deleteSchedule(const std::string& name);

  /**
   * @brief Rename a schedule with @p oldName to @p newName
   * @pre newName.length() != 0
   *
   * @throw Error if update operation fails, e.g., a schedule with @p newName already exists
   */
  void
  renameSchedule(const std::string& oldName, const std::string& newName);

  /**
   * @brief Update the schedule with @p name and replace the old object with @p schedule
   *
   * if no schedule with @p name exists, a new schedule
   * with @p name and @p schedule will be added to database
   */
  void
  updateSchedule(const std::string& name, const Schedule& schedule);

  ////////////////////////////////////////////////////// member management

  /**
   * @brief Check if there is a member with name @p identity
   */
  bool
  hasMember(const Name& identity) const;

  /**
   * @brief List all the members
   */
  std::list<Name>
  listAllMembers() const;

  /**
   * @brief Get the schedule name of a member with name @p identity
   *
   * @throw Error if there is no member with name @p identity in database
   */
  std::string
  getMemberSchedule(const Name& identity) const;

  /**
   * @brief Add a new member with @p key of @p keyName
   *        into a schedule with name @p scheduleName.
   *
   * @throw Error when there's no schedule named @p scheduleName
   * @throw Error if add operation fails, e.g., the added member exists
   */
  void
  addMember(const std::string& scheduleName, const Name& keyName, const Buffer& key);

  /**
   * @brief Change the schedule of a member with name @p identity to a schedule with @p scheduleName
   *
   * @throw Error when there's no schedule named @p scheduleName
   */
  void
  updateMemberSchedule(const Name& identity, const std::string& scheduleName);

  /**
   * @brief Delete a member with name @p identity from database
   */
  void
  deleteMember(const Name& identity);

  /**
   * @brief Check if there is a EKey with name @p eKeyName in database
   */
  bool
  hasEKey(const Name& eKeyName);

  /**
   * @brief Add a EKey with name @p eKeyName to database
   *
   * @p pubKey The public Key of the group key pair
   * @p priKey The private Key of the group key pair
   */
  void
  addEKey(const Name& eKeyName, const Buffer& pubKey, const Buffer& priKey);

  /**
   * @brief Get the group key pair from database
   */
  std::tuple<Buffer, Buffer>
  getEKey(const Name& eKeyName);

  /**
   * @brief Delete all the EKeys in the database
   *
   * The database will keep growing because EKeys will keep being added. The method
   * should be called periodically
   */
  void
  cleanEKeys();

  /**
   * @brief Delete a EKey with name @p eKeyName from database
   */
  void
  deleteEKey(const Name& eKeyName);

private:
  class Impl;
  unique_ptr<Impl> m_impl;
};

} // namespace nac
} // namespace ndn

#endif // GEP_GROUP_MANAGER_DB_HPP
