#include "serialize.h"

int PaEncodeDriverCommand(const PaDriverCommand_t *command, void *memory,
                          uint32_t *size_memory) {
  if (!command || !memory || !size_memory) {
    return -1;
  }
  // Encode the command type as DER(BER)
  asn_enc_rval_t result_encode = der_encode_to_buffer(&asn_DEF_PaDriverCommand,
                                                      (void *)command,
                                                      memory, *size_memory);
  if (result_encode.encoded == -1) {
    return -1;
  }

  *size_memory = result_encode.encoded;

  return 0;
}

int PaDecodeDriverCommand(const void *memory, const uint32_t size_buffer,
                          PaDriverCommand_t** command) {
  if (NULL == command) {
    return -1;
  }
  // Encode the command type as DER
  asn_dec_rval_t result_decode = ber_decode(0, &asn_DEF_PaDriverCommand,
                                            (void **) command,
                                            memory, size_buffer);
  if (result_decode.code != RC_OK) {
    return -1;
  }

  return 0;
}

int PaEncodeDriverCommandResponse(
    const PaDriverCommandResponse_t *command_response, void *memory,
    uint32_t *buffer_size) {
  if (!command_response || !buffer_size) {
    return -1;
  }
  // Encode the command type as DER(BER)
  asn_enc_rval_t result_encode = der_encode_to_buffer(
      &asn_DEF_PaDriverCommandResponse, (void *)command_response, memory, *buffer_size);
  if (result_encode.encoded == -1) {
    return -1;
  }

  *buffer_size = result_encode.encoded;

  return 0;
}


int PaDecodeDriverCommandResponse(
    const void *memory, const uint32_t size_buffer,
    PaDriverCommandResponse_t** command_response) {
  if (!memory || !command_response) {
    return -1;
  }
  // Encode the command type as DER
  asn_dec_rval_t result_decode = ber_decode(0, &asn_DEF_PaDriverCommandResponse,
                                            (void **) command_response,
                                            memory, size_buffer);
  if (result_decode.code != RC_OK) {
    return -1;
  }

  return 0;
}

void PaFreeDriverCommandResponse(PaDriverCommandResponse_t *command_response) {
  if (!command_response) {
    return;
  }

  ASN_STRUCT_FREE(asn_DEF_PaDriverCommandResponse, command_response);
}

int PaEncodePaData(const PaData_t *command, void *memory,
                   uint32_t *size_buffer) {
  if (NULL == command || size_buffer == NULL) {
    return -1;
  }
  // Encode the command type as DER(BER)
  asn_enc_rval_t result_encode = der_encode_to_buffer(&asn_DEF_PaData,
                                                      (void *)command,
                                                      memory, *size_buffer);
  if (result_encode.encoded == -1) {
    return -1;
  }

  *size_buffer = result_encode.encoded;

  return 0;
}

int PaDecodeCertificate(const void *memory, const uint32_t memory_size,
                        PaCertificate_t **certificate) {
  if (!memory || !certificate) {
    return -1;
  }

  // Encode the command type as DER
  asn_dec_rval_t decoded_result = ber_decode(0, &asn_DEF_PaCertificate,
                                             (void **)certificate, memory,
                                             memory_size);
  if (decoded_result.code != RC_OK) {
    return -1;
  }

  return 0;
}

int PaEncodeCertificate(const PaCertificate_t *certificate,
                        void *memory, uint32_t *size) {
  if (!certificate || !memory || !size) {
    return -1;
  }
  // Encode the command type as DER(BER)
  asn_enc_rval_t result_encode = der_encode_to_buffer(&asn_DEF_PaCertificate,
                                                      (void *)certificate,
                                                      memory, *size);
  if (result_encode.encoded == -1) {
    return -1;
  }

  *size = result_encode.encoded;

  return 0;
}

void PaFreeCertificate(PaCertificate_t *certificate) {
  if (!certificate) {
    return;
  }

  ASN_STRUCT_FREE(asn_DEF_PaCertificate, certificate);
}
