/**
 * @author: Jeff Thompson
 * Derived from ContentObject.js by Meki Cheraoui.
 * See COPYING for copyright and distribution information.
 */

#include "BinaryXMLEncoder.h"
#include "BinaryXMLDecoder.h"
#include "BinaryXMLName.h"
#include "BinaryXMLPublisherPublicKeyDigest.h"
#include "binary-xml-data.h"

static ndn_Error encodeSignature(struct ndn_Signature *signature, struct ndn_BinaryXmlEncoder *encoder)
{
  ndn_Error error;
  if (error = ndn_BinaryXmlEncoder_writeElementStartDTag(encoder, ndn_BinaryXml_DTag_Signature))
    return error;
  
  // TODO: Check if digestAlgorithm is the same as the default, and skip it, otherwise encode it as UDATA.

  if (error = ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement
      (encoder, ndn_BinaryXml_DTag_Witness, signature->witness, signature->witnessLength))
    return error;

  // Require a signature.
  if (error = ndn_BinaryXmlEncoder_writeBlobDTagElement
      (encoder, ndn_BinaryXml_DTag_SignatureBits, signature->signature, signature->signatureLength))
    return error;
  
	if (error = ndn_BinaryXmlEncoder_writeElementClose(encoder))
    return error;
  
  return 0;    
}

static ndn_Error decodeSignature(struct ndn_Signature *signature, struct ndn_BinaryXmlDecoder *decoder)
{
  ndn_Error error;
  if (error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_Signature))
    return error;
  
  /* TODO: digestAlgorithm as UDATA */ signature->digestAlgorithm = 0; signature->digestAlgorithmLength = 0;
  
  if (error = ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
      (decoder, ndn_BinaryXml_DTag_Witness, 0, &signature->witness, &signature->witnessLength))
    return error;
  
  // Require a signature.
  if (error = ndn_BinaryXmlDecoder_readBinaryDTagElement
      (decoder, ndn_BinaryXml_DTag_SignatureBits, 0, &signature->signature, &signature->signatureLength))
    return error;
  
  if (error = ndn_BinaryXmlDecoder_readElementClose(decoder))
    return error;
  
  return 0;
}

static ndn_Error encodeSignedInfo(struct ndn_SignedInfo *signedInfo, struct ndn_BinaryXmlEncoder *encoder)
{
  if (signedInfo->type < 0)
    return 0;

  ndn_Error error;
  if (error = ndn_BinaryXmlEncoder_writeElementStartDTag(encoder, ndn_BinaryXml_DTag_SignedInfo))
    return error;

  // This will skip encoding if there is no publisherPublicKeyDigest.
  if (error = ndn_encodeBinaryXmlPublisherPublicKeyDigest(&signedInfo->publisherPublicKeyDigest, encoder))
    return error;
  
  if (error = ndn_BinaryXmlEncoder_writeOptionalTimeMillisecondsDTagElement
      (encoder, ndn_BinaryXml_DTag_Timestamp, signedInfo->timestampMilliseconds))
    return error;
  
  if (signedInfo->type != ndn_ContentType_DATA) {
    // Not the default of DATA, so we need to encode the type.
    // TODO: Implement converting the type from an int and encoding.
  }
  
  if (error = ndn_BinaryXmlEncoder_writeOptionalUnsignedDecimalIntDTagElement
      (encoder, ndn_BinaryXml_DTag_FreshnessSeconds, signedInfo->freshnessSeconds))
    return error;
  
  if (error = ndn_BinaryXmlEncoder_writeOptionalBlobDTagElement
      (encoder, ndn_BinaryXml_DTag_FinalBlockID, signedInfo->finalBlockID, signedInfo->finalBlockIDLength))
    return error;
 
  // This will skip encoding if there is no key locator.
  if (error = ndn_encodeBinaryXmlKeyLocator(&signedInfo->keyLocator, encoder))
    return error;
  
	if (error = ndn_BinaryXmlEncoder_writeElementClose(encoder))
    return error;
  
  return 0;  
}

static ndn_Error decodeSignedInfo(struct ndn_SignedInfo *signedInfo, struct ndn_BinaryXmlDecoder *decoder)
{
  ndn_Error error;
  if (error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_SignedInfo))
    return error;
  
  if (error = ndn_decodeOptionalBinaryXmlPublisherPublicKeyDigest(&signedInfo->publisherPublicKeyDigest, decoder))
    return error;
  
  if (error= ndn_BinaryXmlDecoder_readOptionalTimeMillisecondsDTagElement
      (decoder, ndn_BinaryXml_DTag_Timestamp, &signedInfo->timestampMilliseconds))
    return error;
  
  // TODO: Implement reading the type and converting to an int.
  signedInfo->type = ndn_ContentType_DATA;
 
  if (error = ndn_BinaryXmlDecoder_readOptionalUnsignedIntegerDTagElement
      (decoder, ndn_BinaryXml_DTag_FreshnessSeconds, &signedInfo->freshnessSeconds))
    return error;

  if (error = ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
      (decoder, ndn_BinaryXml_DTag_FinalBlockID, 0, &signedInfo->finalBlockID, &signedInfo->finalBlockIDLength))
    return error;

  if (error = ndn_decodeOptionalBinaryXmlKeyLocator(&signedInfo->keyLocator, decoder))
    return error;
  
  if (error = ndn_BinaryXmlDecoder_readElementClose(decoder))
    return error;
  
  return 0;
}

ndn_Error ndn_encodeBinaryXmlData(struct ndn_Data *data, struct ndn_BinaryXmlEncoder *encoder)
{
  ndn_Error error;
  if (error = ndn_BinaryXmlEncoder_writeElementStartDTag(encoder, ndn_BinaryXml_DTag_ContentObject))
    return error;
  
  if (error = encodeSignature(&data->signature, encoder))
    return 0;

  if (error = ndn_encodeBinaryXmlName(&data->name, encoder))
    return error;

  if (error = encodeSignedInfo(&data->signedInfo, encoder))
    return 0;

  if (error = ndn_BinaryXmlEncoder_writeBlobDTagElement
      (encoder, ndn_BinaryXml_DTag_Content, data->content, data->contentLength))
    return error;
  
	if (error = ndn_BinaryXmlEncoder_writeElementClose(encoder))
    return error;
  
  return 0;
}

ndn_Error ndn_decodeBinaryXmlData(struct ndn_Data *data, struct ndn_BinaryXmlDecoder *decoder)
{
  ndn_Error error;
  if (error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_ContentObject))
    return error;

  int gotExpectedTag;
  if (error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_Signature, &gotExpectedTag))
    return error;
  if (gotExpectedTag) {
    if (error = decodeSignature(&data->signature, decoder))
      return error;
  }
  else
    ndn_Signature_init(&data->signature);
  
  if (error = ndn_decodeBinaryXmlName(&data->name, decoder))
    return error;
  
  if (error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_SignedInfo, &gotExpectedTag))
    return error;
  if (gotExpectedTag) {
    if (error = decodeSignedInfo(&data->signedInfo, decoder))
      return error;
  }
  else
    ndn_SignedInfo_init(&data->signedInfo);

  // Require a Content element, but set allowNull to allow a missing BLOB.
  if (error = ndn_BinaryXmlDecoder_readBinaryDTagElement
      (decoder, ndn_BinaryXml_DTag_Content, 1, &data->content, &data->contentLength))
    return error; 
  
  if (error = ndn_BinaryXmlDecoder_readElementClose(decoder))
    return error;
  
  return 0;
}
