/* -*- 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 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(istream& 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

}
