/* -*- 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()
{
  cout << "Seq File Name: " << m_seqFileNameWithPath << endl;
  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;
}

ostream&
operator<<(ostream& os, const SequencingManager& sm)
{
  std::cout << "----SequencingManager----" << std::endl;
  std::cout << "Adj LSA seq no: " << sm.getAdjLsaSeq() << endl;
  std::cout << "Cor LSA Seq no: " << sm.getCorLsaSeq() << endl;
  std::cout << "Name LSA Seq no: " << sm.getNameLsaSeq() << endl;
  std::cout << "Combined LSDB Seq no: " << sm.getCombinedSeqNo() << endl;
  return os;
}

}//namespace nlsr


