/*
 *
 * 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>
#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "buffer.h"
#include "util.h"

struct pn_buffer_t {
  size_t capacity;
  size_t start;
  size_t size;
  char *bytes;
};

pn_buffer_t *pn_buffer(size_t capacity)
{
  pn_buffer_t *buf = (pn_buffer_t *) malloc(sizeof(pn_buffer_t));
  if (buf != NULL) {
    buf->capacity = capacity;
    buf->start = 0;
    buf->size = 0;
    if (capacity > 0) {
        buf->bytes = (char *)malloc(capacity);
        if (buf->bytes == NULL) {
            free(buf);
            buf = NULL;
        }
    }
    else {
        buf->bytes = NULL;
    }
  }
  return buf;
}

void pn_buffer_free(pn_buffer_t *buf)
{
  if (buf) {
    free(buf->bytes);
    free(buf);
  }
}

size_t pn_buffer_size(pn_buffer_t *buf)
{
  return buf->size;
}

size_t pn_buffer_capacity(pn_buffer_t *buf)
{
  return buf->capacity;
}

size_t pn_buffer_available(pn_buffer_t *buf)
{
  return buf->capacity - buf->size;
}

static size_t pni_buffer_head(pn_buffer_t *buf)
{
  return buf->start;
}

static size_t pni_buffer_tail(pn_buffer_t *buf)
{
  size_t tail = buf->start + buf->size;
  if (tail >= buf->capacity)
    tail -= buf->capacity;
  return tail;
}

static bool pni_buffer_wrapped(pn_buffer_t *buf)
{
  return buf->size && pni_buffer_head(buf) >= pni_buffer_tail(buf);
}

static size_t pni_buffer_tail_space(pn_buffer_t *buf)
{
  if (pni_buffer_wrapped(buf)) {
    return pn_buffer_available(buf);
  } else {
    return buf->capacity - pni_buffer_tail(buf);
  }
}

static size_t pni_buffer_head_space(pn_buffer_t *buf)
{
  if (pni_buffer_wrapped(buf)) {
    return pn_buffer_available(buf);
  } else {
    return pni_buffer_head(buf);
  }
}

static size_t pni_buffer_head_size(pn_buffer_t *buf)
{
  if (pni_buffer_wrapped(buf)) {
    return buf->capacity - pni_buffer_head(buf);
  } else {
    return pni_buffer_tail(buf) - pni_buffer_head(buf);
  }
}

static size_t pni_buffer_tail_size(pn_buffer_t *buf)
{
  if (pni_buffer_wrapped(buf)) {
    return pni_buffer_tail(buf);
  } else {
    return 0;
  }
}

int pn_buffer_ensure(pn_buffer_t *buf, size_t size)
{
  size_t old_capacity = buf->capacity;
  size_t old_head = pni_buffer_head(buf);
  bool wrapped = pni_buffer_wrapped(buf);

  while (pn_buffer_available(buf) < size) {
    buf->capacity = 2*(buf->capacity ? buf->capacity : 16);
  }

  if (buf->capacity != old_capacity) {
    char* new_bytes = (char *)realloc(buf->bytes, buf->capacity);
    if (new_bytes) {
      buf->bytes = new_bytes;

      if (wrapped) {
          size_t n = old_capacity - old_head;
          memmove(buf->bytes + buf->capacity - n, buf->bytes + old_head, n);
          buf->start = buf->capacity - n;
      }
    }
  }

  return 0;
}

int pn_buffer_append(pn_buffer_t *buf, const char *bytes, size_t size)
{
  int err = pn_buffer_ensure(buf, size);
  if (err) return err;

  size_t tail = pni_buffer_tail(buf);
  size_t tail_space = pni_buffer_tail_space(buf);
  size_t n = pn_min(tail_space, size);

  memmove(buf->bytes + tail, bytes, n);
  memmove(buf->bytes, bytes + n, size - n);

  buf->size += size;

  return 0;
}

int pn_buffer_prepend(pn_buffer_t *buf, const char *bytes, size_t size)
{
  int err = pn_buffer_ensure(buf, size);
  if (err) return err;

  size_t head = pni_buffer_head(buf);
  size_t head_space = pni_buffer_head_space(buf);
  size_t n = pn_min(head_space, size);

  memmove(buf->bytes + head - n, bytes + size - n, n);
  memmove(buf->bytes + buf->capacity - (size - n), bytes, size - n);

  if (buf->start >= size) {
    buf->start -= size;
  } else {
    buf->start = buf->capacity - (size - buf->start);
  }

  buf->size += size;

  return 0;
}

static size_t pni_buffer_index(pn_buffer_t *buf, size_t index)
{
  size_t result = buf->start + index;
  if (result >= buf->capacity) result -= buf->capacity;
  return result;
}

size_t pn_buffer_get(pn_buffer_t *buf, size_t offset, size_t size, char *dst)
{
  size = pn_min(size, buf->size);
  size_t start = pni_buffer_index(buf, offset);
  size_t stop = pni_buffer_index(buf, offset + size);

  if (size == 0) return 0;

  size_t sz1;
  size_t sz2;

  if (start >= stop) {
    sz1 = buf->capacity - start;
    sz2 = stop;
  } else {
    sz1 = stop - start;
    sz2 = 0;
  }

  memmove(dst, buf->bytes + start, sz1);
  memmove(dst + sz1, buf->bytes, sz2);

  return sz1 + sz2;
}

int pn_buffer_trim(pn_buffer_t *buf, size_t left, size_t right)
{
  if (left + right > buf->size) return PN_ARG_ERR;

  buf->start += left;
  if (buf->start >= buf->capacity)
    buf->start -= buf->capacity;

  buf->size -= left + right;

  return 0;
}

void pn_buffer_clear(pn_buffer_t *buf)
{
  buf->start = 0;
  buf->size = 0;
}

static void pn_buffer_rotate (pn_buffer_t *buf, size_t sz) {
  if (sz == 0) return;

  unsigned c = 0, v = 0;
  for (; c < buf->capacity; v++) {
    unsigned t = v, tp = v + sz;
    char tmp = buf->bytes[v];
    c++;
    while (tp != v) {
      buf->bytes[t] = buf->bytes[tp];
      t = tp;
      tp += sz;
      if (tp >= buf->capacity) tp -= buf->capacity;
      c++;
    }
    buf->bytes[t] = tmp;
  }
}

int pn_buffer_defrag(pn_buffer_t *buf)
{
  pn_buffer_rotate(buf, buf->start);
  buf->start = 0;
  return 0;
}

pn_bytes_t pn_buffer_bytes(pn_buffer_t *buf)
{
  if (buf) {
    pn_buffer_defrag(buf);
    return pn_bytes(buf->size, buf->bytes);
  } else {
    return pn_bytes(0, NULL);
  }
}

pn_buffer_memory_t pn_buffer_memory(pn_buffer_t *buf)
{
  if (buf) {
    pn_buffer_defrag(buf);
    pn_buffer_memory_t r = {buf->size, buf->bytes};
    return r;
  } else {
    pn_buffer_memory_t r = {0, NULL};
    return r;
  }
}

int pn_buffer_print(pn_buffer_t *buf)
{
  printf("pn_buffer(\"");
  pn_print_data(buf->bytes + pni_buffer_head(buf), pni_buffer_head_size(buf));
  pn_print_data(buf->bytes, pni_buffer_tail_size(buf));
  printf("\")");
  return 0;
}
