/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014,  Regents of the University of California.
 *
 * This file is part of NDN repo-ng (Next generation of NDN repository).
 * See AUTHORS.md for complete list of repo-ng authors and contributors.
 *
 * repo-ng 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.
 *
 * repo-ng 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
 * repo-ng, e.g., in COPYING.md file.  if (not, see <http://www.gnu.org/licenses/>.
 */

#include "../src/common.hpp"
#include "config.hpp"
#include <string>
#include <sqlite3.h>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>

namespace repo {

using std::string;

void
printUsage(const char* programName)
{

  std::cout
    << "Usage:\n"
    << "  " << programName << " [-c <path/to/repo-ng.conf>] [-n] [-h]\n"
    << "\n"
    << "List names of Data packets in NDN repository. "
    << "By default, all names will include the implicit digest of Data packets\n"
    << "\n"
    << "Options:\n"
    << "  -h: show help message\n"
    << "  -c: set config file path\n"
    << "  -n: do not show implicit digest\n"
    << std::endl;
  ;
}

class RepoEnumerator
{
public:
  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

public:
  RepoEnumerator(const std::string& configFile);

  uint64_t
  enumerate(bool showImplicitDigest);

private:
  void
  readConfig(const std::string& configFile);

private:
  sqlite3* m_db;
  std::string m_dbPath;
};

RepoEnumerator::RepoEnumerator(const std::string& configFile)
{
  readConfig(configFile);
  char* errMsg = 0;
  int rc = sqlite3_open_v2(m_dbPath.c_str(), &m_db,
                           SQLITE_OPEN_READONLY,
   #ifdef DISABLE_SQLITE3_FS_LOCKING
                            "unix-dotfile"
   #else
                            0
   #endif
                          );
  if (rc != SQLITE_OK) {
    throw Error("Database file open failure");
  }
  sqlite3_exec(m_db, "PRAGMA synchronous = OFF", 0, 0, &errMsg);
  sqlite3_exec(m_db, "PRAGMA journal_mode = WAL", 0, 0, &errMsg);
}

void
RepoEnumerator::readConfig(const std::string& configFile)
{
  if (configFile.empty()) {
    throw Error("Invalid configuration file name");
  }

  std::ifstream fin(configFile.c_str());
  if (!fin.is_open())
    throw Error("failed to open configuration file '" + configFile + "'");

  using namespace boost::property_tree;
  ptree propertyTree;
  try {
    read_info(fin, propertyTree);
  }
  catch (ptree_error& e) {
    throw Error("failed to read configuration file '" + configFile + "'");
  }
  ptree repoConf = propertyTree.get_child("repo");
  m_dbPath = repoConf.get<std::string>("storage.path");
  m_dbPath += "/ndn_repo.db";
}

uint64_t
RepoEnumerator::enumerate(bool showImplicitDigest)
{
  sqlite3_stmt* m_stmt = 0;
  int rc = SQLITE_DONE;
  string sql = string("SELECT id, name, keylocatorHash FROM NDN_REPO;");
  rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &m_stmt, 0);
  if (rc != SQLITE_OK)
    throw Error("Initiation Read Entries from Database Prepare error");
  uint64_t entryNumber = 0;
  while (true) {
    rc = sqlite3_step(m_stmt);
    if (rc == SQLITE_ROW) {
      Name name;
      name.wireDecode(Block(sqlite3_column_blob(m_stmt, 1),
                            sqlite3_column_bytes(m_stmt, 1)));
      try {
        if (showImplicitDigest) {
          std::cout << name << std::endl;
        }
        else {
          std::cout << name.getPrefix(-1) << std::endl;
        }
      }
      catch (...){
        sqlite3_finalize(m_stmt);
        throw;
      }
      entryNumber++;
    }
    else if (rc == SQLITE_DONE) {
      sqlite3_finalize(m_stmt);
      break;
    }
    else {
      sqlite3_finalize(m_stmt);
      throw Error("Initiation Read Entries error");
    }
  }
  return entryNumber;
}

int
main(int argc, char** argv)
{
  string configPath = DEFAULT_CONFIG_FILE;
  bool showImplicitDigest = true;
  int opt;
  while ((opt = getopt(argc, argv, "hc:n")) != -1) {
    switch (opt) {
    case 'h':
      printUsage(argv[0]);
      return 0;
    case 'c':
      configPath = string(optarg);
      break;
    case 'n':
      showImplicitDigest = false;
      break;
    default:
      break;
    }
  }

  RepoEnumerator instance(configPath);
  uint64_t count = instance.enumerate(showImplicitDigest);
  std::cerr << "Total number of data = " << count << std::endl;
  return 0;
}

} // namespace repo


int
main(int argc, char** argv)
{
  try {
    return repo::main(argc, argv);
  }
  catch (std::exception& e) {
    std::cerr << "ERROR: " << e.what() << std::endl;
    return 2;
  }
}
