/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#if 1 // TODO: Remove this when we don't throw "not implemented".
#include <stdexcept>
#endif
#include "der-exception.hpp"
#include "../../util/logging.hpp"
#include "der.hpp"

INIT_LOGGER("ndn.der.DER");

using namespace std;
using namespace ndn::ptr_lib;

namespace ndn {

namespace der {

/*
 * DerNode
 */
DerNode::DerNode()
  :parent_(0)
{}

DerNode::DerNode(DerType type)
  :type_(type),
   parent_(0)
{}

DerNode::DerNode(InputIterator& start)
  :parent_(0)
{
  decode(start);
}

DerNode::~DerNode()
{}

void
DerNode::encodeHeader(int size)
{
  header_.push_back((char)type_);

  if (size >= 127) {
    int val = size;
    char buf[sizeof(val) + 1];
    char *p = &(buf[sizeof(buf)-1]);
    int n = 0;
    int mask = (1 << 8) - 1;

    while (val != 0) {
      p[0] = (char)(val & mask);
      p--;
      n++;
      val >>= 8;
    }

    p[0] = (char)((1<<7) | n);
    n++;

    header_.insert(header_.end(), p, p+n);
  }
  else if (size >= 0)
    header_.push_back((char)size);
  else
    throw NegativeLengthException("Negative length");
}

int
DerNode::decodeHeader(InputIterator& start)
{
  uint8_t type = start.ReadU8();
  // char type = start.get();
  header_.push_back(type);
  type_ = static_cast<DerType>((int)type);

  uint8_t sizeLen = start.ReadU8(); 
  // char sizeLen = start.get();
  header_.push_back(sizeLen);

  bool longFormat = sizeLen & (1 << 7);

  if (!longFormat) {
    // _LOG_DEBUG("Short Format");
    // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
    return (int)sizeLen;
  }
  else {
    // _LOG_DEBUG("Long Format");
    uint8_t byte;
    // char byte;
    int lenCount = sizeLen & ((1<<7) - 1);
    // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
    // _LOG_DEBUG("mask: " << (int)((1<<7) - 1));
    // _LOG_DEBUG("lenCount: " << (int)lenCount);
    int size = 0;
    do {
      byte = start.ReadU8();
      header_.push_back(byte);
      size = size * 256 + (int)byte;
      // _LOG_DEBUG("byte: " << (int)byte);
      // _LOG_DEBUG("size: " << size);
      lenCount--;
    } while (lenCount > 0);

    return size;
  }
}

void
DerNode::encode(OutputIterator& start)
{
  start.write((const char*)&header_[0], header_.size());
  start.write((const char*)&payload_[0], payload_.size());
}

void 
DerNode::decode(InputIterator& start)
{
  int payloadSize = decodeHeader(start);
  // _LOG_DEBUG("payloadSize: " << payloadSize);
  if (payloadSize > 0 ) {
    char buf[payloadSize];
    start.read(buf, payloadSize);
    payload_.insert(payload_.end(), buf, buf + payloadSize);
  }
}

shared_ptr<DerNode>
DerNode::parse(InputIterator& start)
{
  int type = ((uint8_t)start.PeekU8());

  // _LOG_DEBUG("Type: " << hex << setw(2) << setfill('0') << type);
  switch(type) {
    case DER_BOOLEAN:
      return shared_ptr<DerBool>(new DerBool(start));
    case DER_INTEGER:
      return shared_ptr<DerInteger>(new DerInteger(start));
    case DER_BIT_STRING:
      return shared_ptr<DerBitString>(new DerBitString(start));
    case DER_OCTET_STRING:
      return shared_ptr<DerOctetString>(new DerOctetString(start));
    case DER_NULL:
      return shared_ptr<DerNull>(new DerNull(start));
    case DER_OBJECT_IDENTIFIER:
      return shared_ptr<DerOid>(new DerOid(start));
    case DER_SEQUENCE:
      return shared_ptr<DerSequence>(new DerSequence(start));
    case DER_PRINTABLE_STRING:
      return shared_ptr<DerPrintableString>(new DerPrintableString(start));
    case DER_GENERALIZED_TIME:
      return shared_ptr<DerGtime>(new DerGtime(start));
    default:
      throw DerDecodingException("Unimplemented DER types");
  }
}


/*
 * DerComplex
 */
DerComplex::DerComplex()
  :DerNode(),
   childChanged_(false),
   size_(0)
{}

DerComplex::DerComplex(DerType type)
  :DerNode(type),
   childChanged_(false),
   size_(0)
{}

DerComplex::DerComplex(InputIterator& start)
  :DerNode(),
   childChanged_(false),
   size_(0)
{
  size_ = DerNode::decodeHeader(start);
  // _LOG_DEBUG("Size: " << size_);

  int accSize = 0;
  
  while (accSize < size_) {
    // _LOG_DEBUG("accSize: " << accSize);
    shared_ptr<DerNode> nodePtr = DerNode::parse(start);
    accSize += nodePtr->getSize();
    addChild(nodePtr, false);
  }
}

DerComplex::~DerComplex()
{}

int
DerComplex::getSize()
{
  if (childChanged_) {
    updateSize();
    childChanged_ = false;
  }

  header_.clear();
  DerNode::encodeHeader(size_);
  return size_ + header_.size();
}

Blob
DerComplex::getRaw()
{
  shared_ptr<vector<uint8_t> > blob(new vector<uint8_t>());
  blob->insert(blob->end(), header_.begin(), header_.end());

  DerNodePtrList::iterator it = nodeList_.begin();
  for (; it != nodeList_.end(); it++) {
    Blob childBlob = (*it)->getRaw();
    blob->insert(blob->end(), childBlob->begin(), childBlob->end());
  }
  return blob;
}

void
DerComplex::updateSize()
{
  int newSize = 0;

  DerNodePtrList::iterator it = nodeList_.begin();
  for (; it != nodeList_.end(); it++) {
    newSize += (*it)->getSize();
  }
  
  size_ = newSize;
  childChanged_ = false;
}

void
DerComplex::addChild(shared_ptr<DerNode> nodePtr, bool notifyParent)
{
  nodePtr->setParent(this);

  nodeList_.push_back(nodePtr);

  if (!notifyParent)
    return;

  if (childChanged_)
    return;
  else
    childChanged_ = true;

  if (0 != parent_)
    parent_->setChildChanged();
}

void
DerComplex::setChildChanged()
{
  if (0 != parent_ && !childChanged_) {
    parent_->setChildChanged();
    childChanged_ = true;
  }
  else
    childChanged_ = true;
}

void
DerComplex::encode(OutputIterator& start)
{
  updateSize();
  header_.clear();

  DerNode::encodeHeader(size_);

  start.write((const char*)&header_[0], header_.size());

  DerNodePtrList::iterator it = nodeList_.begin();
  for (; it != nodeList_.end(); it++)
    (*it)->encode(start);
}


/*
 * DerByteString
 */
DerByteString::DerByteString(const string& str, DerType type)
  :DerNode(type)
{
  payload_.insert(payload_.end(), str.begin(), str.end());

  DerNode::encodeHeader(payload_.size());
}

DerByteString::DerByteString(const std::vector<uint8_t>& blob, DerType type)
  :DerNode(type)
{
  payload_.insert(payload_.end(), blob.begin(), blob.end());

  DerNode::encodeHeader(payload_.size());
}

DerByteString::DerByteString(InputIterator& start)
  :DerNode(start)
{}

DerByteString::~DerByteString()
{}


/*
 * DerBool
 */
DerBool::DerBool(bool value)
  :DerNode(DER_BOOLEAN)

{ 
  char payload = (value ? 0xFF : 0x00);
  payload_.push_back(payload);

  DerNode::encodeHeader(payload_.size());
}

DerBool::DerBool(InputIterator& start)
  :DerNode(start)
{}

DerBool::~DerBool()
{}


/*
 * DerInteger
 */
DerInteger::DerInteger(const vector<uint8_t>& blob)
  :DerNode(DER_INTEGER)
{
  payload_.insert(payload_.end(), blob.begin(), blob.end());

  DerNode::encodeHeader(payload_.size());
}

DerInteger::DerInteger(InputIterator& start)
  :DerNode(start)
{}

DerInteger::~DerInteger()
{}


/*
 * DerBitString
 */
DerBitString::DerBitString(const vector<uint8_t>& blob, uint8_t paddingLen)
  :DerNode(DER_BIT_STRING)
{     
  payload_.push_back((char)paddingLen);
  payload_.insert(payload_.end(), blob.begin(), blob.end());

  DerNode::encodeHeader(payload_.size());
}

DerBitString::DerBitString(InputIterator& start)
  :DerNode(start)
{}

DerBitString::~DerBitString()
{}


/*
 * DerOctetString
 */
DerOctetString::DerOctetString(const string& str)
  :DerByteString(str, DER_OCTET_STRING)
{}

DerOctetString::DerOctetString(const vector<uint8_t>& blob)
  :DerByteString(blob, DER_OCTET_STRING)
{}

DerOctetString::DerOctetString(InputIterator& start)
  :DerByteString(start)
{}

DerOctetString::~DerOctetString()
{}


/*
 * DerNull
 */
DerNull::DerNull()
  :DerNode(DER_NULL)
{
  DerNode::encodeHeader(0);
}

DerNull::DerNull(InputIterator& start)
  :DerNode(start)
{}
  
DerNull::~DerNull()
{}


/*
 * DerOid
 */
DerOid::DerOid(const OID& oid)
  :DerNode(DER_OBJECT_IDENTIFIER)
{
  prepareEncoding(oid.getIntegerList());
}


DerOid::DerOid(const string& oidStr)
  :DerNode(DER_OBJECT_IDENTIFIER)
{
  vector<int> value;

  string str = oidStr + ".";

  size_t pos = 0;
  size_t ppos = 0;

  while (string::npos != pos) {
    ppos = pos;

    pos = str.find_first_of('.', pos);
    if (string::npos == pos)
      break;

    value.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));

    pos++;
  }

  prepareEncoding(value);
}

DerOid::DerOid(const vector<int>& value)
  :DerNode(DER_OBJECT_IDENTIFIER)
{
  prepareEncoding(value);
}

DerOid::DerOid(InputIterator& start)
  :DerNode(start)
{}
  
DerOid::~DerOid()
{}

void
DerOid::prepareEncoding(const vector<int>& value)
{
  ostringstream os;

  int firstNumber = 0;
  
  if (value.size() >= 1) {
    if (0 <= value[0] && 2 >= value[0])
      firstNumber = value[0] * 40;
    else
      throw DerEncodingException("first integer of oid is out of range");
  }
  else
    throw DerEncodingException("no integer in oid");

  if (value.size() >= 2) {
    if (0 <= value[1] && 39 >= value[1])
      firstNumber += value[1];
    else
      throw DerEncodingException("second integer of oid is out of range");
  }
  
  encode128(firstNumber, os);

  if (value.size() > 2) {
    int i = 2;
    for (; i < value.size(); i++)
      encode128(value[i], os);
  }

  string output = os.str();
  DerNode::encodeHeader(output.size());

  payload_.insert(payload_.end(), output.begin(), output.end());
}
  
void
DerOid::encode128(int value, ostringstream& os)
{
  int mask = (1 << 7) - 1;

  if (128 > value) {
    uint8_t singleByte = (uint8_t) mask & value;
    os.write((char *)&singleByte, 1);
  }
  else {
    uint8_t buf[(sizeof(value)*8 + 6)/7 + 1];
    uint8_t *p = &(buf[sizeof(buf)-1]);
    int n = 1;

    p[0] = (uint8_t)(value & mask);
    value >>= 7;

    while (value != 0) {
      (--p)[0] = (uint8_t)((value & mask) | (1 << 7));
      n++;
      value >>= 7;
    }
    
    os.write((char *)p, n);
  }
}

int
DerOid::decode128(int & offset)
{
  uint8_t flagMask = 0x80;
  int result = 0;
  while (payload_[offset] & flagMask) {
    result = 128 * result + (uint8_t) payload_[offset] - 128;
    offset++;
  }

  result = result * 128 + payload_[offset];
  offset++;

  return result;
}


/*
 * DerSequence
 */
DerSequence::DerSequence()
  :DerComplex(DER_SEQUENCE)
{}

DerSequence::DerSequence(InputIterator& start)
  :DerComplex(start)
{}

DerSequence::~DerSequence() 
{}


/*
 * DerPrintableString
 */
DerPrintableString::DerPrintableString(const string& str)
  :DerByteString(str, DER_PRINTABLE_STRING)
{}

DerPrintableString::DerPrintableString(const vector<uint8_t>& blob)
  :DerByteString(blob, DER_PRINTABLE_STRING)
{}

DerPrintableString::DerPrintableString(InputIterator& start)
  :DerByteString(start)
{}

DerPrintableString::~DerPrintableString()
{}


/*
 * DerGtime
 */
DerGtime::DerGtime(const MillisecondsSince1970& time)
  :DerNode(DER_GENERALIZED_TIME)
{
  string pTimeStr = toIsoString(time);
  int index = pTimeStr.find_first_of('T');
  string derTime = pTimeStr.substr(0, index) + pTimeStr.substr(index+1, pTimeStr.size() - index -1) + "Z";
  payload_.insert(payload_.end(), derTime.begin(), derTime.end());

  DerNode::encodeHeader(payload_.size());
}

DerGtime::DerGtime(InputIterator& start)
  :DerNode(start)
{}
  
DerGtime::~DerGtime()
{}

string DerGtime::toIsoString(const MillisecondsSince1970& time)
{
#if 1
  throw std::runtime_error("not implemented");
#endif
}

MillisecondsSince1970 DerGtime::fromIsoString(const string& isoString)
{
#if 1
  throw std::runtime_error("not implemented");
#endif
}

} // der

}
