/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

#include <proton/error.h>
#include <proton/object.h>
#include <proton/codec.h>
#include "encodings.h"
#include "encoder.h"

#include <string.h>

#include "data.h"

struct pn_encoder_t {
  char *output;
  size_t size;
  char *position;
  pn_error_t *error;
};

static void pn_encoder_initialize(void *obj)
{
  pn_encoder_t *encoder = (pn_encoder_t *) obj;
  encoder->output = NULL;
  encoder->size = 0;
  encoder->position = NULL;
  encoder->error = pn_error();
}

static void pn_encoder_finalize(void *obj) {
  pn_encoder_t *encoder = (pn_encoder_t *) obj;
  pn_error_free(encoder->error);
}

#define pn_encoder_hashcode NULL
#define pn_encoder_compare NULL
#define pn_encoder_inspect NULL

pn_encoder_t *pn_encoder()
{
  static const pn_class_t clazz = PN_CLASS(pn_encoder);
  return (pn_encoder_t *) pn_class_new(&clazz, sizeof(pn_encoder_t));
}

static uint8_t pn_type2code(pn_encoder_t *encoder, pn_type_t type)
{
  switch (type)
  {
  case PN_NULL: return PNE_NULL;
  case PN_BOOL: return PNE_BOOLEAN;
  case PN_UBYTE: return PNE_UBYTE;
  case PN_BYTE: return PNE_BYTE;
  case PN_USHORT: return PNE_USHORT;
  case PN_SHORT: return PNE_SHORT;
  case PN_UINT: return PNE_UINT;
  case PN_INT: return PNE_INT;
  case PN_CHAR: return PNE_UTF32;
  case PN_FLOAT: return PNE_FLOAT;
  case PN_LONG: return PNE_LONG;
  case PN_TIMESTAMP: return PNE_MS64;
  case PN_DOUBLE: return PNE_DOUBLE;
  case PN_DECIMAL32: return PNE_DECIMAL32;
  case PN_DECIMAL64: return PNE_DECIMAL64;
  case PN_DECIMAL128: return PNE_DECIMAL128;
  case PN_UUID: return PNE_UUID;
  case PN_ULONG: return PNE_ULONG;
  case PN_BINARY: return PNE_VBIN32;
  case PN_STRING: return PNE_STR32_UTF8;
  case PN_SYMBOL: return PNE_SYM32;
  case PN_LIST: return PNE_LIST32;
  case PN_ARRAY: return PNE_ARRAY32;
  case PN_MAP: return PNE_MAP32;
  case PN_DESCRIBED: return PNE_DESCRIPTOR;
  default:
    return pn_error_format(encoder->error, PN_ERR, "not a value type: %u\n", type);
  }
}

static uint8_t pn_node2code(pn_encoder_t *encoder, pni_node_t *node)
{
  switch (node->atom.type) {
  case PN_LONG:
    if (-128 <= node->atom.u.as_long && node->atom.u.as_long <= 127) {
      return PNE_SMALLLONG;
    } else {
      return PNE_LONG;
    }
  case PN_INT:
    if (-128 <= node->atom.u.as_int && node->atom.u.as_int <= 127) {
      return PNE_SMALLINT;
    } else {
      return PNE_INT;
    }
  case PN_ULONG:
    if (node->atom.u.as_ulong < 256) {
      return PNE_SMALLULONG;
    } else {
      return PNE_ULONG;
    }
  case PN_UINT:
    if (node->atom.u.as_uint < 256) {
      return PNE_SMALLUINT;
    } else {
      return PNE_UINT;
    }
  case PN_BOOL:
    if (node->atom.u.as_bool) {
      return PNE_TRUE;
    } else {
      return PNE_FALSE;
    }
  case PN_STRING:
    if (node->atom.u.as_bytes.size < 256) {
      return PNE_STR8_UTF8;
    } else {
      return PNE_STR32_UTF8;
    }
  case PN_SYMBOL:
    if (node->atom.u.as_bytes.size < 256) {
      return PNE_SYM8;
    } else {
      return PNE_SYM32;
    }
  case PN_BINARY:
    if (node->atom.u.as_bytes.size < 256) {
      return PNE_VBIN8;
    } else {
      return PNE_VBIN32;
    }
  default:
    return pn_type2code(encoder, node->atom.type);
  }
}

static size_t pn_encoder_remaining(pn_encoder_t *encoder) {
  char * end = encoder->output + encoder->size;
  if (end > encoder->position)
    return end - encoder->position;
  else
    return 0;
}

static inline void pn_encoder_writef8(pn_encoder_t *encoder, uint8_t value)
{
  if (pn_encoder_remaining(encoder)) {
    encoder->position[0] = value;
  }
  encoder->position++;
}

static inline void pn_encoder_writef16(pn_encoder_t *encoder, uint16_t value)
{
  if (pn_encoder_remaining(encoder) >= 2) {
    encoder->position[0] = 0xFF & (value >> 8);
    encoder->position[1] = 0xFF & (value     );
  }
  encoder->position += 2;
}

static inline void pn_encoder_writef32(pn_encoder_t *encoder, uint32_t value)
{
  if (pn_encoder_remaining(encoder) >= 4) {
    encoder->position[0] = 0xFF & (value >> 24);
    encoder->position[1] = 0xFF & (value >> 16);
    encoder->position[2] = 0xFF & (value >>  8);
    encoder->position[3] = 0xFF & (value      );
  }
  encoder->position += 4;
}

static inline void pn_encoder_writef64(pn_encoder_t *encoder, uint64_t value) {
  if (pn_encoder_remaining(encoder) >= 8) {
    encoder->position[0] = 0xFF & (value >> 56);
    encoder->position[1] = 0xFF & (value >> 48);
    encoder->position[2] = 0xFF & (value >> 40);
    encoder->position[3] = 0xFF & (value >> 32);
    encoder->position[4] = 0xFF & (value >> 24);
    encoder->position[5] = 0xFF & (value >> 16);
    encoder->position[6] = 0xFF & (value >>  8);
    encoder->position[7] = 0xFF & (value      );
  }
  encoder->position += 8;
}

static inline void pn_encoder_writef128(pn_encoder_t *encoder, char *value) {
  if (pn_encoder_remaining(encoder) >= 16) {
    memmove(encoder->position, value, 16);
  }
  encoder->position += 16;
}

static inline void pn_encoder_writev8(pn_encoder_t *encoder, const pn_bytes_t *value)
{
  pn_encoder_writef8(encoder, value->size);
  if (pn_encoder_remaining(encoder) >= value->size)
    memmove(encoder->position, value->start, value->size);
  encoder->position += value->size;
}

static inline void pn_encoder_writev32(pn_encoder_t *encoder, const pn_bytes_t *value)
{
  pn_encoder_writef32(encoder, value->size);
  if (pn_encoder_remaining(encoder) >= value->size)
    memmove(encoder->position, value->start, value->size);
  encoder->position += value->size;
}

/* True if node is an element of an array - not the descriptor. */
static bool pn_is_in_array(pn_data_t *data, pni_node_t *parent, pni_node_t *node) {
  return (parent && parent->atom.type == PN_ARRAY) /* In array */
    && !(parent->described && !node->prev); /* Not the descriptor */
}

/** True if node is the first element of an array, not the descriptor.
 *@pre pn_is_in_array(data, parent, node)
 */
static bool pn_is_first_in_array(pn_data_t *data, pni_node_t *parent, pni_node_t *node) {
  if (!node->prev) return !parent->described; /* First node */
  return parent->described && (!pn_data_node(data, node->prev)->prev);
}

typedef union {
  uint32_t i;
  uint32_t a[2];
  uint64_t l;
  float f;
  double d;
} conv_t;

static int pni_encoder_enter(void *ctx, pn_data_t *data, pni_node_t *node)
{
  pn_encoder_t *encoder = (pn_encoder_t *) ctx;
  pni_node_t *parent = pn_data_node(data, node->parent);
  pn_atom_t *atom = &node->atom;
  uint8_t code;
  conv_t c;

  /** In an array we don't write the code before each element, only the first. */
  if (pn_is_in_array(data, parent, node)) {
    code = pn_type2code(encoder, parent->type);
    if (pn_is_first_in_array(data, parent, node)) {
      pn_encoder_writef8(encoder, code);
    }
  } else {
    code = pn_node2code(encoder, node);
    pn_encoder_writef8(encoder, code);
  }

  switch (code) {
  case PNE_DESCRIPTOR:
  case PNE_NULL:
  case PNE_TRUE:
  case PNE_FALSE: return 0;
  case PNE_BOOLEAN: pn_encoder_writef8(encoder, atom->u.as_bool); return 0;
  case PNE_UBYTE: pn_encoder_writef8(encoder, atom->u.as_ubyte); return 0;
  case PNE_BYTE: pn_encoder_writef8(encoder, atom->u.as_byte); return 0;
  case PNE_USHORT: pn_encoder_writef16(encoder, atom->u.as_ushort); return 0;
  case PNE_SHORT: pn_encoder_writef16(encoder, atom->u.as_short); return 0;
  case PNE_UINT0: return 0;
  case PNE_SMALLUINT: pn_encoder_writef8(encoder, atom->u.as_uint); return 0;
  case PNE_UINT: pn_encoder_writef32(encoder, atom->u.as_uint); return 0;
  case PNE_SMALLINT: pn_encoder_writef8(encoder, atom->u.as_int); return 0;
  case PNE_INT: pn_encoder_writef32(encoder, atom->u.as_int); return 0;
  case PNE_UTF32: pn_encoder_writef32(encoder, atom->u.as_char); return 0;
  case PNE_ULONG: pn_encoder_writef64(encoder, atom->u.as_ulong); return 0;
  case PNE_SMALLULONG: pn_encoder_writef8(encoder, atom->u.as_ulong); return 0;
  case PNE_LONG: pn_encoder_writef64(encoder, atom->u.as_long); return 0;
  case PNE_SMALLLONG: pn_encoder_writef8(encoder, atom->u.as_long); return 0;
  case PNE_MS64: pn_encoder_writef64(encoder, atom->u.as_timestamp); return 0;
  case PNE_FLOAT: c.f = atom->u.as_float; pn_encoder_writef32(encoder, c.i); return 0;
  case PNE_DOUBLE: c.d = atom->u.as_double; pn_encoder_writef64(encoder, c.l); return 0;
  case PNE_DECIMAL32: pn_encoder_writef32(encoder, atom->u.as_decimal32); return 0;
  case PNE_DECIMAL64: pn_encoder_writef64(encoder, atom->u.as_decimal64); return 0;
  case PNE_DECIMAL128: pn_encoder_writef128(encoder, atom->u.as_decimal128.bytes); return 0;
  case PNE_UUID: pn_encoder_writef128(encoder, atom->u.as_uuid.bytes); return 0;
  case PNE_VBIN8: pn_encoder_writev8(encoder, &atom->u.as_bytes); return 0;
  case PNE_VBIN32: pn_encoder_writev32(encoder, &atom->u.as_bytes); return 0;
  case PNE_STR8_UTF8: pn_encoder_writev8(encoder, &atom->u.as_bytes); return 0;
  case PNE_STR32_UTF8: pn_encoder_writev32(encoder, &atom->u.as_bytes); return 0;
  case PNE_SYM8: pn_encoder_writev8(encoder, &atom->u.as_bytes); return 0;
  case PNE_SYM32: pn_encoder_writev32(encoder, &atom->u.as_bytes); return 0;
  case PNE_ARRAY32:
    node->start = encoder->position;
    node->small = false;
    // we'll backfill the size on exit
    encoder->position += 4;
    pn_encoder_writef32(encoder, node->described ? node->children - 1 : node->children);
    if (node->described)
      pn_encoder_writef8(encoder, 0);
    return 0;
  case PNE_LIST32:
  case PNE_MAP32:
    node->start = encoder->position;
    node->small = false;
    // we'll backfill the size later
    encoder->position += 4;
    pn_encoder_writef32(encoder, node->children);
    return 0;
  default:
    return pn_error_format(data->error, PN_ERR, "unrecognized encoding: %u", code);
  }
}

#include <stdio.h>

static int pni_encoder_exit(void *ctx, pn_data_t *data, pni_node_t *node)
{
  pn_encoder_t *encoder = (pn_encoder_t *) ctx;
  char *pos;

  switch (node->atom.type) {
  case PN_ARRAY:
    if ((node->described && node->children == 1) || (!node->described && node->children == 0)) {
      pn_encoder_writef8(encoder, pn_type2code(encoder, node->type));
    }
  case PN_LIST:
  case PN_MAP:
    pos = encoder->position;
    encoder->position = node->start;
    if (node->small) {
      // backfill size
      size_t size = pos - node->start - 1;
      pn_encoder_writef8(encoder, size);
    } else {
      // backfill size
      size_t size = pos - node->start - 4;
      pn_encoder_writef32(encoder, size);
    }
    encoder->position = pos;
    return 0;
  default:
    return 0;
  }
}

ssize_t pn_encoder_encode(pn_encoder_t *encoder, pn_data_t *src, char *dst, size_t size)
{
  encoder->output = dst;
  encoder->position = dst;
  encoder->size = size;

  int err = pni_data_traverse(src, pni_encoder_enter, pni_encoder_exit, encoder);
  if (err) return err;
  size_t encoded = encoder->position - encoder->output;
  if (encoded > size) {
      pn_error_format(pn_data_error(src), PN_OVERFLOW, "not enough space to encode");
      return PN_OVERFLOW;
  }
  return (ssize_t)encoded;
}

ssize_t pn_encoder_size(pn_encoder_t *encoder, pn_data_t *src)
{
  encoder->output = 0;
  encoder->position = 0;
  encoder->size = 0;

  pn_handle_t save = pn_data_point(src);
  int err = pni_data_traverse(src, pni_encoder_enter, pni_encoder_exit, encoder);
  pn_data_restore(src, save);

  if (err) return err;
  return encoder->position - encoder->output;
}
