/* -*- 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(std::istream& 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(istream& start)
{
  uint8_t type = start.get();
  // char type = start.get();
  header_.push_back(type);
  type_ = static_cast<DerType>((int)type);

  uint8_t sizeLen = start.get(); 
  // 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.get();
          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(ostream& start)
{
  start.write((const char*)&header_[0], header_.size());
  start.write((const char*)&payload_[0], payload_.size());
}

void 
DerNode::decode(istream& 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(istream& start)
{
  int type = ((uint8_t)start.peek());

  // _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(istream& 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();
}

shared_ptr<vector<uint8_t> >
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++)
    {
      shared_ptr<vector<uint8_t> > 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(ostream& 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(istream& 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(istream& 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(istream& 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(istream& 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(istream& start)
  :DerByteString(start)
{}

DerOctetString::~DerOctetString()
{}


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

DerNull::DerNull(istream& 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(istream& 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(istream& 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(istream& start)
  :DerByteString(start)
{}

DerPrintableString::~DerPrintableString()
{}


/*
 * DerGtime
 */
DerGtime::DerGtime(const Time& 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(istream& start)
  :DerNode(start)
{}
  
DerGtime::~DerGtime()
{}

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

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

} // der

}
