/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017, Regents of the University of California.
 *
 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
 *
 * ChronoShare 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.
 *
 * ChronoShare 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 copies of the GNU General Public License along with
 * ChronoShare, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
 */

#include "object-manager.hpp"
#include "ccnx-common.hpp"
#include "ccnx-name.hpp"
#include "ccnx-pco.hpp"
#include "logging.hpp"
#include "object-db.hpp"

#include <sys/stat.h>

#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/throw_exception.hpp>
#include <fstream>

_LOG_INIT(Object.Manager);

using namespace Ndnx;
using namespace boost;
using namespace std;
namespace fs = boost::filesystem;

const int MAX_FILE_SEGMENT_SIZE = 1024;

ObjectManager::ObjectManager(Ccnx::CcnxWrapperPtr ccnx, const fs::path& folder,
                             const std::string& appName)
  : m_ccnx(ccnx)
  , m_folder(folder / ".chronoshare")
  , m_appName(appName)
{
  fs::create_directories(m_folder);
}

ObjectManager::~ObjectManager()
{
}

// /<devicename>/<appname>/file/<hash>/<segment>
boost::tuple<HashPtr /*object-db name*/, size_t /* number of segments*/>
ObjectManager::localFileToObjects(const fs::path& file, const Ccnx::Name& deviceName)
{
  HashPtr fileHash = Hash::FromFileContent(file);
  ObjectDb fileDb(m_folder, lexical_cast<string>(*fileHash));

  fs::ifstream iff(file, std::ios::in | std::ios::binary);
  sqlite3_int64 segment = 0;
  while (iff.good() && !iff.eof()) {
    char buf[MAX_FILE_SEGMENT_SIZE];
    iff.read(buf, MAX_FILE_SEGMENT_SIZE);
    if (iff.gcount() == 0) {
      // stupid streams...
      break;
    }

    Name name = Name("/")(deviceName)(m_appName)("file")(fileHash->GetHash(),
                                                         fileHash->GetHashBytes())(segment);

    // cout << *fileHash << endl;
    // cout << name << endl;
    //_LOG_DEBUG ("Read " << iff.gcount () << " from " << file << " for segment " << segment);

    Bytes data = m_ccnx->createContentObject(name, buf, iff.gcount());
    fileDb.saveContentObject(deviceName, segment, data);

    segment++;
  }
  if (segment == 0) // handle empty files
  {
    Name name =
      Name("/")(m_appName)("file")(fileHash->GetHash(), fileHash->GetHashBytes())(deviceName)(0);
    Bytes data = m_ccnx->createContentObject(name, 0, 0);
    fileDb.saveContentObject(deviceName, 0, data);

    segment++;
  }

  return make_tuple(fileHash, segment);
}

bool
ObjectManager::objectsToLocalFile(/*in*/ const Ccnx::Name& deviceName, /*in*/ const Hash& fileHash,
                                  /*out*/ const fs::path& file)
{
  string hashStr = lexical_cast<string>(fileHash);
  if (!ObjectDb::DoesExist(m_folder, deviceName, hashStr)) {
    _LOG_ERROR("ObjectDb for [" << m_folder << ", " << deviceName << ", " << hashStr
                                << "] does not exist or not all segments are available");
    return false;
  }

  if (!exists(file.parent_path())) {
    create_directories(file.parent_path());
  }

  fs::ofstream off(file, std::ios::out | std::ios::binary);
  ObjectDb fileDb(m_folder, hashStr);

  sqlite3_int64 segment = 0;
  BytesPtr bytes = fileDb.fetchSegment(deviceName, 0);
  while (bytes) {
    ParsedContentObject obj(*bytes);
    BytesPtr data = obj.contentPtr();

    if (data) {
      off.write(reinterpret_cast<const char*>(head(*data)), data->size());
    }

    segment++;
    bytes = fileDb.fetchSegment(deviceName, segment);
  }

  // permission and timestamp should be assigned somewhere else (ObjectManager has no idea about that)

  return true;
}
