/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017, Regents of the University of California
 *
 * This file is part of NDN DeLorean, An Authentication System for Data Archives in
 * Named Data Networking.  See AUTHORS.md for complete list of NDN DeLorean authors
 * and contributors.
 *
 * NDN DeLorean 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.
 *
 * NDN DeLorean 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 NDN
 * DeLorean, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "logger-response.hpp"
#include "tlv.hpp"

namespace nsl {

LoggerResponse::LoggerResponse()
  : m_code(-1)
{
}

LoggerResponse::LoggerResponse(int32_t code, const std::string& msg)
  : m_code(code)
  , m_msg(msg)
  , m_dataSeqNo(0)
{
}

LoggerResponse::LoggerResponse(const NonNegativeInteger& seqNo)
  : m_code(0)
  , m_dataSeqNo(seqNo)
{
}

template<ndn::encoding::Tag TAG>
size_t
LoggerResponse::wireEncode(ndn::EncodingImpl<TAG>& block) const
{
  size_t totalLength = 0;

  if (m_code != 0) {
    totalLength += block.prependByteArrayBlock(tlv::ResultMsg,
                                               reinterpret_cast<const uint8_t*>(m_msg.c_str()),
                                               m_msg.size());
  }
  else {
    totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::DataSeqNo, m_dataSeqNo);
  }
  totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::ResultCode, m_code);

  totalLength += block.prependVarNumber(totalLength);
  totalLength += block.prependVarNumber(tlv::LogResponse);

  return totalLength;
}

template size_t
LoggerResponse::wireEncode<ndn::encoding::EncoderTag>(ndn::EncodingImpl<ndn::encoding::EncoderTag>&) const;

template size_t
LoggerResponse::wireEncode<ndn::encoding::EstimatorTag>(ndn::EncodingImpl<ndn::encoding::EstimatorTag>&) const;


const Block&
LoggerResponse::wireEncode() const
{
  if (m_wire.hasWire())
    return m_wire;

  ndn::EncodingEstimator estimator;
  size_t estimatedSize = wireEncode(estimator);

  ndn::EncodingBuffer buffer(estimatedSize, 0);
  wireEncode(buffer);

  m_wire = buffer.block();
  return m_wire;
}

void
LoggerResponse::wireDecode(const Block& wire)
{
  if (!wire.hasWire()) {
    throw Error("The supplied block does not contain wire format");
  }

  m_wire = wire;
  m_wire.parse();

  if (m_wire.type() != tlv::LogResponse)
    throw tlv::Error("Unexpected TLV type when decoding log response");

  Block::element_const_iterator it = m_wire.elements_begin();

  // the first block must be result code
  if (it != m_wire.elements_end() && it->type() == tlv::ResultCode) {
    m_code = readNonNegativeInteger(*it);
    it++;
  }
  else
    throw Error("The first sub-TLV is not ResultCode");

  // the second block could be result msg
  if (it == m_wire.elements_end())
    return;
  else if (it->type() == tlv::ResultMsg) {
    m_msg = std::string(reinterpret_cast<const char*>(it->value()), it->value_size());
    it++;
  }
  else if (it->type() == tlv::DataSeqNo) {
    m_dataSeqNo = readNonNegativeInteger(*it);
    it++;
  }
  else
    throw Error("The second sub-TLV is not ResultMsg");

  if (it != m_wire.elements_end())
    throw Error("No more sub-TLV in log response");
}

} // namespace nsl
