/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013, Regents of the University of California
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#include "common.hpp"

#include "block.hpp"
#include "tlv.hpp"
#include "encoding-buffer.hpp"

namespace ndn {

Block::Block()
  : m_type(std::numeric_limits<uint32_t>::max())
{
}

Block::Block(const EncodingBuffer& buffer)
  : m_buffer(buffer.m_buffer)
  , m_begin(buffer.begin())
  , m_end(buffer.end())
  , m_size(m_end - m_begin)
{
  m_value_begin = m_begin;
  m_value_end   = m_end;

  m_type = Tlv::readType(m_value_begin, m_value_end);
  uint64_t length = Tlv::readVarNumber(m_value_begin, m_value_end);
  if (length != static_cast<uint64_t>(m_value_end - m_value_begin))
    {
      throw Tlv::Error("TLV length doesn't match buffer length");
    }
}

Block::Block(const ConstBufferPtr &wire,
             uint32_t type,
             const Buffer::const_iterator &begin, const Buffer::const_iterator &end,
             const Buffer::const_iterator &valueBegin, const Buffer::const_iterator &valueEnd)
  : m_buffer(wire)
  , m_type(type)
  , m_begin(begin)
  , m_end(end)
  , m_size(m_end - m_begin)
  , m_value_begin(valueBegin)
  , m_value_end(valueEnd)
{
}

Block::Block(const ConstBufferPtr &buffer)
  : m_buffer(buffer)
  , m_begin(m_buffer->begin())
  , m_end(m_buffer->end())
  , m_size(m_end - m_begin)
{
  m_value_begin = m_begin;
  m_value_end   = m_end;

  m_type = Tlv::readType(m_value_begin, m_value_end);

  uint64_t length = Tlv::readVarNumber(m_value_begin, m_value_end);
  if (length != static_cast<uint64_t>(m_value_end - m_value_begin))
    {
      throw Tlv::Error("TLV length doesn't match buffer length");
    }
}

Block::Block(const ConstBufferPtr &buffer,
             const Buffer::const_iterator &begin, const Buffer::const_iterator &end,
             bool verifyLength/* = true*/)
  : m_buffer(buffer)
  , m_begin(begin)
  , m_end(end)
  , m_size(m_end - m_begin)
{
  m_value_begin = m_begin;
  m_value_end   = m_end;

  m_type = Tlv::readType(m_value_begin, m_value_end);
  uint64_t length = Tlv::readVarNumber(m_value_begin, m_value_end);
  if (verifyLength)
    {
      if (length != static_cast<uint64_t>(m_value_end - m_value_begin))
        {
          throw Tlv::Error("TLV length doesn't match buffer length");
        }
    }
}

Block::Block(std::istream& is)
{
  std::istream_iterator<uint8_t> tmp_begin(is);
  std::istream_iterator<uint8_t> tmp_end;

  m_type = Tlv::readType(tmp_begin, tmp_end);
  uint64_t length = Tlv::readVarNumber(tmp_begin, tmp_end);

  // We may still have some problem here, if some exception happens in this constructor, we may completely lose all the bytes extracted from the stream.

  OBufferStream os;
  size_t headerLength = Tlv::writeVarNumber(os, m_type);
  headerLength += Tlv::writeVarNumber(os, length);

  char* buf = new char[length];
  buf[0] = *tmp_begin;
  is.read(buf+1, length-1);

  if(length != static_cast<uint64_t>(is.gcount())+1)
    {
      delete [] buf;
      throw Tlv::Error("Not enough data in the buffer to fully parse TLV");
    }

  os.write(buf, length);
  delete [] buf;

  m_buffer = os.buf();

  m_begin = m_buffer->begin();
  m_end = m_buffer->end();
  m_size = m_end - m_begin;

  m_value_begin = m_buffer->begin() + headerLength;
  m_value_end   = m_buffer->end();
}


Block::Block(const uint8_t *buffer, size_t maxlength)
{
  const uint8_t * tmp_begin = buffer;
  const uint8_t * tmp_end   = buffer + maxlength;

  m_type = Tlv::readType(tmp_begin, tmp_end);
  uint64_t length = Tlv::readVarNumber(tmp_begin, tmp_end);

  if (length > static_cast<uint64_t>(tmp_end - tmp_begin))
    {
      throw Tlv::Error("Not enough data in the buffer to fully parse TLV");
    }

  m_buffer = ptr_lib::make_shared<Buffer> (buffer, (tmp_begin - buffer) + length);

  m_begin = m_buffer->begin();
  m_end = m_buffer->end();
  m_size = m_end - m_begin;

  m_value_begin = m_buffer->begin() + (tmp_begin - buffer);
  m_value_end   = m_buffer->end();
}

Block::Block(const void *bufferX, size_t maxlength)
{
  const uint8_t * buffer = reinterpret_cast<const uint8_t*>(bufferX);

  const uint8_t * tmp_begin = buffer;
  const uint8_t * tmp_end   = buffer + maxlength;

  m_type = Tlv::readType(tmp_begin, tmp_end);
  uint64_t length = Tlv::readVarNumber(tmp_begin, tmp_end);

  if (length > static_cast<uint64_t>(tmp_end - tmp_begin))
    {
      throw Tlv::Error("Not enough data in the buffer to fully parse TLV");
    }

  m_buffer = ptr_lib::make_shared<Buffer> (buffer, (tmp_begin - buffer) + length);

  m_begin = m_buffer->begin();
  m_end = m_buffer->end();
  m_size = m_end - m_begin;

  m_value_begin = m_buffer->begin() + (tmp_begin - buffer);
  m_value_end   = m_buffer->end();
}

Block::Block(uint32_t type)
  : m_type(type)
{
}

Block::Block(uint32_t type, const ConstBufferPtr &value)
  : m_buffer(value)
  , m_type(type)
  , m_begin(m_buffer->end())
  , m_end(m_buffer->end())
  , m_value_begin(m_buffer->begin())
  , m_value_end(m_buffer->end())
{
  m_size = Tlv::sizeOfVarNumber(m_type) + Tlv::sizeOfVarNumber(value_size()) + value_size();
}

Block::Block(uint32_t type, const Block &value)
  : m_buffer(value.m_buffer)
  , m_type(type)
  , m_begin(m_buffer->end())
  , m_end(m_buffer->end())
  , m_value_begin(value.begin())
  , m_value_end(value.end())
{
  m_size = Tlv::sizeOfVarNumber(m_type) + Tlv::sizeOfVarNumber(value_size()) + value_size();
}

bool
Block::fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block)
{
  Buffer::const_iterator tempBegin = wire->begin() + offset;

  uint32_t type;
  bool ok = Tlv::readType(tempBegin, wire->end(), type);
  if (!ok)
    return false;

  uint64_t length;
  ok = Tlv::readVarNumber(tempBegin, wire->end(), length);
  if (!ok)
    return false;

  if (length > static_cast<uint64_t>(wire->end() - tempBegin))
    {
      return false;
    }

  block = Block(wire, type,
                wire->begin() + offset, tempBegin + length,
                tempBegin, tempBegin + length);

  return true;
}

bool
Block::fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block)
{
  const uint8_t* tempBegin = buffer;
  const uint8_t* tempEnd = buffer + maxSize;

  uint32_t type;
  bool ok = Tlv::readType(tempBegin, tempEnd, type);
  if (!ok)
    return false;

  uint64_t length;
  ok = Tlv::readVarNumber(tempBegin, tempEnd, length);
  if (!ok)
    return false;

  if (length > static_cast<uint64_t>(tempEnd - tempBegin))
    {
      return false;
    }

  BufferPtr sharedBuffer = make_shared<Buffer>(buffer, tempBegin + length);
  block = Block(sharedBuffer, type,
                sharedBuffer->begin(), sharedBuffer->end(),
                sharedBuffer->begin() + (tempBegin - buffer), sharedBuffer->end());

  return true;
}

void
Block::parse() const
{
  if (!m_subBlocks.empty() || value_size()==0)
    return;

  Buffer::const_iterator begin = value_begin(),
    end = value_end();

  while (begin != end)
    {
      Buffer::const_iterator element_begin = begin;

      uint32_t type = Tlv::readType(begin, end);
      uint64_t length = Tlv::readVarNumber(begin, end);

      if (length > static_cast<uint64_t>(end - begin))
        {
          m_subBlocks.clear();
          throw Tlv::Error("TLV length exceeds buffer length");
        }
      Buffer::const_iterator element_end = begin + length;

      m_subBlocks.push_back(Block(m_buffer,
                                  type,
                                  element_begin, element_end,
                                  begin, element_end));

      begin = element_end;
      // don't do recursive parsing, just the top level
    }
}

void
Block::encode()
{
  if (hasWire())
    return;

  OBufferStream os;
  Tlv::writeVarNumber(os, type());

  if (hasValue())
    {
      Tlv::writeVarNumber(os, value_size());
      os.write(reinterpret_cast<const char*>(value()), value_size());
    }
  else if (m_subBlocks.size() == 0)
    {
      Tlv::writeVarNumber(os, 0);
    }
  else
    {
      size_t valueSize = 0;
      for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) {
        valueSize += i->size();
      }

      Tlv::writeVarNumber(os, valueSize);

      for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) {
        if (i->hasWire())
          os.write(reinterpret_cast<const char*>(i->wire()), i->size());
        else if (i->hasValue()) {
          Tlv::writeVarNumber(os, i->type());
          Tlv::writeVarNumber(os, i->value_size());
          os.write(reinterpret_cast<const char*>(i->value()), i->value_size());
        }
        else
          throw Error("Underlying value buffer is empty");
      }
    }

  // now assign correct block

  m_buffer = os.buf();
  m_begin = m_buffer->begin();
  m_end   = m_buffer->end();
  m_size  = m_end - m_begin;

  m_value_begin = m_buffer->begin();
  m_value_end   = m_buffer->end();

  Tlv::readType(m_value_begin, m_value_end);
  Tlv::readVarNumber(m_value_begin, m_value_end);
}

Block
Block::blockFromValue() const
{
  if (value_size()==0)
    throw Error("Underlying value buffer is empty");

  Buffer::const_iterator begin = value_begin(),
    end = value_end();

  Buffer::const_iterator element_begin = begin;

  uint32_t type = Tlv::readType(begin, end);
  uint64_t length = Tlv::readVarNumber(begin, end);

  if (length != static_cast<uint64_t>(end - begin))
    throw Tlv::Error("TLV length mismatches buffer length");

  return Block(m_buffer,
               type,
               element_begin, end,
               begin, end);
}

} // namespace ndn
