/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014  University of Memphis,
 *                     Regents of the University of California
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR 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.
 *
 * NLSR 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
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
 *
 **/
#include <string>
#include <iostream>
#include <fstream>
#include <pwd.h>
#include <cstdlib>
#include <unistd.h>

#include "sequencing-manager.hpp"
#include "logger.hpp"

namespace nlsr {

INIT_LOGGER("SequencingManager");

using namespace std;

void
SequencingManager::splittSequenceNo(uint64_t seqNo)
{
  m_combinedSeqNo = seqNo;
  m_adjLsaSeq = (m_combinedSeqNo & 0xFFFFF);
  m_corLsaSeq = ((m_combinedSeqNo >> 20) & 0xFFFFF);
  m_nameLsaSeq = ((m_combinedSeqNo >> 40) & 0xFFFFF);
}

void
SequencingManager::combineSequenceNo()
{
  m_combinedSeqNo = 0;
  m_combinedSeqNo = m_combinedSeqNo | m_adjLsaSeq;
  m_combinedSeqNo = m_combinedSeqNo | (m_corLsaSeq << 20);
  m_combinedSeqNo = m_combinedSeqNo | (m_nameLsaSeq << 40);
}

void
SequencingManager::writeSeqNoToFile()
{
  std::ofstream outputFile(m_seqFileNameWithPath.c_str(), ios::binary);
  outputFile << m_combinedSeqNo;
  outputFile.close();
}

void
SequencingManager::initiateSeqNoFromFile()
{
  _LOG_DEBUG("Seq File Name: " << m_seqFileNameWithPath);
  std::ifstream inputFile(m_seqFileNameWithPath.c_str(), ios::binary);
  if (inputFile.good()) {
    inputFile >> m_combinedSeqNo;
    splittSequenceNo(m_combinedSeqNo);
    m_adjLsaSeq += 10;
    m_corLsaSeq += 10;
    m_nameLsaSeq += 10;
    combineSequenceNo();
    inputFile.close();
  }
  else {
    splittSequenceNo(0);
  }
}

void
SequencingManager::setSeqFileName(string filePath)
{
  m_seqFileNameWithPath = filePath;
  if (m_seqFileNameWithPath.empty()) {
    m_seqFileNameWithPath = getUserHomeDirectory();
  }
  m_seqFileNameWithPath = m_seqFileNameWithPath + "/nlsrSeqNo.txt";
}

string
SequencingManager::getUserHomeDirectory()
{
  string homeDirPath(getpwuid(getuid())->pw_dir);
  if (homeDirPath.empty()) {
    homeDirPath = getenv("HOME");
  }
  return homeDirPath;
}

void
SequencingManager::writeLog()
{
  _LOG_DEBUG("----SequencingManager----");
  _LOG_DEBUG("Adj LSA seq no: " << m_adjLsaSeq);
  _LOG_DEBUG("Cor LSA Seq no: " << m_corLsaSeq);
  _LOG_DEBUG("Name LSA Seq no: " << m_nameLsaSeq);
  _LOG_DEBUG("Combined LSDB Seq no: " << m_combinedSeqNo);
}

}//namespace nlsr


