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

#include "binary-xml.h"
#include "binary-xml-structure-decoder.h"
#include "binary-xml-key.h"

static ndn_Error decodeKeyNameData(struct ndn_KeyLocator *keyLocator, struct ndn_BinaryXmlDecoder *decoder)
{
  int gotExpectedTag;
  ndn_Error error; 
  if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, &gotExpectedTag)))
    return error;
  if (gotExpectedTag) {
    keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST;
    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
        (decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
      return error;
  }
  else {
    if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, &gotExpectedTag)))
      return error;
    if (gotExpectedTag) {
      keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST;
      if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
          (decoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
        return error;
    }
    else {
      if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, &gotExpectedTag)))
        return error;
      if (gotExpectedTag) {
        keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST;
        if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
            (decoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
          return error;
      }
      else {
        if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, &gotExpectedTag)))
          return error;
        if (gotExpectedTag) {
          keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST;
          if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
              (decoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
            return error;
        }
        else {
          // Key name data is omitted.
          keyLocator->keyNameType = -1;
          keyLocator->keyDataLength = 0;
        }
      }
    }
  }
  
  return NDN_ERROR_success;
}

ndn_Error ndn_encodeBinaryXmlKeyLocator(struct ndn_KeyLocator *keyLocator, struct ndn_BinaryXmlEncoder *encoder)
{
  if ((int)keyLocator->type < 0)
    return NDN_ERROR_success;

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

  if (keyLocator->type == ndn_KeyLocatorType_KEY) {
    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
        (encoder, ndn_BinaryXml_DTag_Key, keyLocator->keyData, keyLocator->keyDataLength)))
      return error;    
  }
  else if (keyLocator->type == ndn_KeyLocatorType_CERTIFICATE) {
    if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
        (encoder, ndn_BinaryXml_DTag_Certificate, keyLocator->keyData, keyLocator->keyDataLength)))
      return error;    
  }
  else if (keyLocator->type == ndn_KeyLocatorType_KEYNAME) {
    if ((error = ndn_BinaryXmlEncoder_writeElementStartDTag(encoder, ndn_BinaryXml_DTag_KeyName)))
      return error;
    if ((error = ndn_encodeBinaryXmlName(&keyLocator->keyName, encoder)))
      return error;
    
    if ((int)keyLocator->keyNameType >= 0 && keyLocator->keyDataLength > 0) {
      if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST) {
        if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
            (encoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, keyLocator->keyData, keyLocator->keyDataLength)))
          return error;    
      }
      else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST) {
        if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
            (encoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, keyLocator->keyData, keyLocator->keyDataLength)))
          return error;    
      }
      else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST) {
        if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
            (encoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, keyLocator->keyData, keyLocator->keyDataLength)))
          return error;    
      }
      else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST) {
        if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
            (encoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, keyLocator->keyData, keyLocator->keyDataLength)))
          return error;    
      }
      else
        return NDN_ERROR_unrecognized_ndn_KeyNameType;
    }
    
    if ((error = ndn_BinaryXmlEncoder_writeElementClose(encoder)))
      return error;
  }
  else
    return NDN_ERROR_unrecognized_ndn_KeyLocatorType;
  
  if ((error = ndn_BinaryXmlEncoder_writeElementClose(encoder)))
    return error;
  
  return NDN_ERROR_success;
}

ndn_Error ndn_decodeBinaryXmlKeyLocator(struct ndn_KeyLocator *keyLocator, struct ndn_BinaryXmlDecoder *decoder)
{
  ndn_Error error;
  if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_KeyLocator)))
    return error;

  int gotExpectedTag;
  if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_Key, &gotExpectedTag)))
    return error;
  if (gotExpectedTag) {
    keyLocator->type = ndn_KeyLocatorType_KEY;
    
    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
        (decoder, ndn_BinaryXml_DTag_Key, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
      return error;
  }
  else {
    if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_Certificate, &gotExpectedTag)))
      return error;
    if (gotExpectedTag) {
      keyLocator->type = ndn_KeyLocatorType_CERTIFICATE;
    
      if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
          (decoder, ndn_BinaryXml_DTag_Certificate, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
        return error;
    }
    else {
      if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_KeyName, &gotExpectedTag)))
        return error;
      if (gotExpectedTag) {
        keyLocator->type = ndn_KeyLocatorType_KEYNAME;
        
        if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_KeyName)))
          return error;
        if ((error = ndn_decodeBinaryXmlName(&keyLocator->keyName, decoder)))
          return error;
        if ((error = decodeKeyNameData(keyLocator, decoder)))
          return error;        
        if ((error = ndn_BinaryXmlDecoder_readElementClose(decoder)))
          return error;
      }
      else
        return NDN_ERROR_decodeBinaryXmlKeyLocator_unrecognized_key_locator_type;
    }
  }

  if ((error = ndn_BinaryXmlDecoder_readElementClose(decoder)))
    return error;
  
  return NDN_ERROR_success;
}

ndn_Error ndn_decodeOptionalBinaryXmlKeyLocator(struct ndn_KeyLocator *keyLocator, struct ndn_BinaryXmlDecoder *decoder)
{
  int gotExpectedTag;
  ndn_Error error; 
  if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_KeyLocator, &gotExpectedTag)))
    return error;
  if (gotExpectedTag) {
    if ((error = ndn_decodeBinaryXmlKeyLocator(keyLocator, decoder)))
      return error;
  }
  else
    ndn_KeyLocator_initialize(keyLocator, keyLocator->keyName.components, keyLocator->keyName.maxComponents);
  
  return NDN_ERROR_success;
}
