/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017,  The University of Memphis,
 *                           Regents of the University of California,
 *                           Arizona Board of Regents.
 *
 * 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/>.
 **/

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

#include <string>
#include <iostream>
#include <fstream>
#include <pwd.h>
#include <cstdlib>
#include <unistd.h>
#include <boost/algorithm/string.hpp>

namespace nlsr {

INIT_LOGGER("SequencingManager");

void
SequencingManager::writeSeqNoToFile() const
{
  writeLog();
  std::ofstream outputFile(m_seqFileNameWithPath.c_str());
  std::ostringstream os;
  os << "NameLsaSeq " << std::to_string(m_nameLsaSeq) << "\n"
     << "AdjLsaSeq "  << std::to_string(m_adjLsaSeq)  << "\n"
     << "CorLsaSeq "  << std::to_string(m_corLsaSeq);
  outputFile << os.str();
  outputFile.close();
}

void
SequencingManager::initiateSeqNoFromFile(int hypState)
{
  NLSR_LOG_DEBUG("Seq File Name: " << m_seqFileNameWithPath);
  std::ifstream inputFile(m_seqFileNameWithPath.c_str());

  // Good checks that file is not (bad or eof or fail)
  if (inputFile.good()) {
    std::string lsaOrCombinedSeqNo;
    uint64_t seqNo = 0;

    // If file has a combined seq number, lsaOrCombinedSeqNo would hold it
    // and seqNo will be zero everytime
    inputFile >> lsaOrCombinedSeqNo >> seqNo;
    m_nameLsaSeq = seqNo;

    inputFile >> lsaOrCombinedSeqNo >> seqNo;
    m_adjLsaSeq = seqNo;

    inputFile >> lsaOrCombinedSeqNo >> seqNo;;
    m_corLsaSeq = seqNo;

    // File was in old format and had a combined sequence number
    // if all of the seqNo should are still zero and
    // lsaOrCombinedSeqNo != CorLsaSeq
    if (m_nameLsaSeq == 0 && m_adjLsaSeq == 0 && m_corLsaSeq == 0 &&
        lsaOrCombinedSeqNo != "CorLsaSeq") {
      NLSR_LOG_DEBUG("Old file had combined sequence number: " << lsaOrCombinedSeqNo);
      std::istringstream iss(lsaOrCombinedSeqNo);
      iss >> seqNo;
      m_adjLsaSeq = (seqNo & 0xFFFFF);
      m_corLsaSeq = ((seqNo >> 20) & 0xFFFFF);
      m_nameLsaSeq = ((seqNo >> 40) & 0xFFFFFF);
    }

    inputFile.close();

    m_nameLsaSeq += 10;

    // Increment the adjacency LSA seq. no. if link-state or dry HR is enabled
    if (hypState != HYPERBOLIC_STATE_ON) {
      if (m_corLsaSeq != 0) {
        NLSR_LOG_WARN("This router was previously configured for hyperbolic"
                   << " routing without clearing the seq. no. file.");
        m_corLsaSeq = 0;
      }
      m_adjLsaSeq += 10;
    }

    // Similarly, increment the coordinate LSA seq. no only if link-state is disabled.
    if (hypState != HYPERBOLIC_STATE_OFF) {
      if (m_adjLsaSeq != 0) {
        NLSR_LOG_WARN("This router was previously configured for link-state"
                  << " routing without clearing the seq. no. file.");
        m_adjLsaSeq = 0;
      }
      m_corLsaSeq += 10;
    }
  }
  writeLog();
}

void
SequencingManager::setSeqFileDirectory(std::string filePath)
{
  m_seqFileNameWithPath = filePath;

  if (m_seqFileNameWithPath.empty()) {
    std::string homeDirPath(getpwuid(getuid())->pw_dir);
    if (homeDirPath.empty()) {
      homeDirPath = getenv("HOME");
    }
    m_seqFileNameWithPath = homeDirPath;
  }
  m_seqFileNameWithPath = m_seqFileNameWithPath + "/nlsrSeqNo.txt";
}

void
SequencingManager::writeLog() const
{
  NLSR_LOG_DEBUG("----SequencingManager----");
  NLSR_LOG_DEBUG("Adj LSA seq no: " << m_adjLsaSeq);
  NLSR_LOG_DEBUG("Cor LSA Seq no: " << m_corLsaSeq);
  NLSR_LOG_DEBUG("Name LSA Seq no: " << m_nameLsaSeq);
}

} // namespace nlsr
