/*
The MIT License(MIT)
Copyright(c) 2016 Peter Goldsborough

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#define __STDC_WANT_LIB_EXT1__ 1

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "third_party/vector/vector.h"

/***** PRIVATE *****/
#define MAX(a, b) ((a) > (b) ? (a) : (b))

static bool _vector_should_grow(Vector *vector) {
  assert(vector->size <= vector->capacity);
  return vector->size == vector->capacity;
}

static bool _vector_should_shrink(Vector *vector) {
  assert(vector->size <= vector->capacity);
  return vector->size == vector->capacity * VECTOR_SHRINK_THRESHOLD;
}

static void *_vector_offset(Vector *vector, size_t index) {
  // return vector->data + (index * vector->element_size);
  return (unsigned char *)vector->data + (index * vector->element_size);
}

static const void *_vector_const_offset(const Vector *vector, size_t index) {
  // return vector->data + (index * vector->element_size);
  return (unsigned char *)vector->data + (index * vector->element_size);
}

static void _vector_assign(Vector *vector, size_t index, void *element) {
  /* Insert the element */
  void *offset = _vector_offset(vector, index);
  memcpy(offset, element, vector->element_size);
}

static int _vector_move_right(Vector *vector, size_t index) {
  assert(vector->size < vector->capacity);

  /* The location where to start to move from. */
  void *offset = _vector_offset(vector, index);

  /* How many to move to the right. */
  size_t elements_in_bytes = (vector->size - index) * vector->element_size;

#ifdef __STDC_LIB_EXT1__
  size_t right_capacity_in_bytes =
      (vector->capacity - (index + 1)) * vector->element_size;

  /* clang-format off */
    int return_code =  memmove_s(
        offset + vector->element_size,
        right_capacity_in_bytes,
        offset,
        elements_in_bytes);

  /* clang-format on */

  return return_code == 0 ? VECTOR_SUCCESS : VECTOR_ERROR;

#else
  // memmove(offset + vector->element_size, offset, elements_in_bytes);
  memmove((unsigned char *)offset + vector->element_size, offset,
          elements_in_bytes);
  return VECTOR_SUCCESS;
#endif
}

static void _vector_move_left(Vector *vector, size_t index) {
  size_t right_elements_in_bytes;
  void *offset;

  /* The offset into the memory */
  offset = _vector_offset(vector, index);

  /* How many to move to the left */
  right_elements_in_bytes = (vector->size - index - 1) * vector->element_size;

  // memmove(offset, offset + vector->element_size, right_elements_in_bytes);
  memmove(offset, (unsigned char *)offset + vector->element_size,
          right_elements_in_bytes);
}

static int _vector_reallocate(Vector *vector, size_t new_capacity) {
  size_t new_capacity_in_bytes;
  void *old;
  assert(vector != NULL);

  if (new_capacity < VECTOR_MINIMUM_CAPACITY) {
    if (vector->capacity > VECTOR_MINIMUM_CAPACITY) {
      new_capacity = VECTOR_MINIMUM_CAPACITY;
    } else {
      /* NO-OP */
      return VECTOR_SUCCESS;
    }
  }

  new_capacity_in_bytes = new_capacity * vector->element_size;
  old = vector->data;

  if ((vector->data = malloc(new_capacity_in_bytes)) == NULL) {
    return VECTOR_ERROR;
  }

#ifdef __STDC_LIB_EXT1__
  /* clang-format off */
    if (memcpy_s(vector->data,
                             new_capacity_in_bytes,
                             old,
                             aom_vector_byte_size(vector)) != 0) {
        return VECTOR_ERROR;
    }
/* clang-format on */
#else
  memcpy(vector->data, old, aom_vector_byte_size(vector));
#endif

  vector->capacity = new_capacity;

  free(old);

  return VECTOR_SUCCESS;
}

static int _vector_adjust_capacity(Vector *vector) {
  return _vector_reallocate(vector,
                            MAX(1, vector->size * VECTOR_GROWTH_FACTOR));
}

static void _vector_swap(size_t *first, size_t *second) {
  size_t temp = *first;
  *first = *second;
  *second = temp;
}

int aom_vector_setup(Vector *vector, size_t capacity, size_t element_size) {
  assert(vector != NULL);

  if (vector == NULL) return VECTOR_ERROR;

  vector->size = 0;
  vector->capacity = MAX(VECTOR_MINIMUM_CAPACITY, capacity);
  vector->element_size = element_size;
  vector->data = malloc(vector->capacity * element_size);

  return vector->data == NULL ? VECTOR_ERROR : VECTOR_SUCCESS;
}

int aom_vector_copy(Vector *destination, Vector *source) {
  assert(destination != NULL);
  assert(source != NULL);
  assert(aom_vector_is_initialized(source));
  assert(!aom_vector_is_initialized(destination));

  if (destination == NULL) return VECTOR_ERROR;
  if (source == NULL) return VECTOR_ERROR;
  if (aom_vector_is_initialized(destination)) return VECTOR_ERROR;
  if (!aom_vector_is_initialized(source)) return VECTOR_ERROR;

  /* Copy ALL the data */
  destination->size = source->size;
  destination->capacity = source->size * 2;
  destination->element_size = source->element_size;

  /* Note that we are not necessarily allocating the same capacity */
  destination->data = malloc(destination->capacity * source->element_size);
  if (destination->data == NULL) return VECTOR_ERROR;

  memcpy(destination->data, source->data, aom_vector_byte_size(source));

  return VECTOR_SUCCESS;
}

int aom_vector_copy_assign(Vector *destination, Vector *source) {
  assert(destination != NULL);
  assert(source != NULL);
  assert(aom_vector_is_initialized(source));
  assert(aom_vector_is_initialized(destination));

  if (destination == NULL) return VECTOR_ERROR;
  if (source == NULL) return VECTOR_ERROR;
  if (!aom_vector_is_initialized(destination)) return VECTOR_ERROR;
  if (!aom_vector_is_initialized(source)) return VECTOR_ERROR;

  aom_vector_destroy(destination);

  return aom_vector_copy(destination, source);
}

int aom_vector_move(Vector *destination, Vector *source) {
  assert(destination != NULL);
  assert(source != NULL);

  if (destination == NULL) return VECTOR_ERROR;
  if (source == NULL) return VECTOR_ERROR;

  *destination = *source;
  source->data = NULL;

  return VECTOR_SUCCESS;
}

int aom_vector_move_assign(Vector *destination, Vector *source) {
  aom_vector_swap(destination, source);
  return aom_vector_destroy(source);
}

int aom_vector_swap(Vector *destination, Vector *source) {
  void *temp;

  assert(destination != NULL);
  assert(source != NULL);
  assert(aom_vector_is_initialized(source));
  assert(aom_vector_is_initialized(destination));

  if (destination == NULL) return VECTOR_ERROR;
  if (source == NULL) return VECTOR_ERROR;
  if (!aom_vector_is_initialized(destination)) return VECTOR_ERROR;
  if (!aom_vector_is_initialized(source)) return VECTOR_ERROR;

  _vector_swap(&destination->size, &source->size);
  _vector_swap(&destination->capacity, &source->capacity);
  _vector_swap(&destination->element_size, &source->element_size);

  temp = destination->data;
  destination->data = source->data;
  source->data = temp;

  return VECTOR_SUCCESS;
}

int aom_vector_destroy(Vector *vector) {
  assert(vector != NULL);

  if (vector == NULL) return VECTOR_ERROR;

  free(vector->data);
  vector->data = NULL;

  return VECTOR_SUCCESS;
}

/* Insertion */
int aom_vector_push_back(Vector *vector, void *element) {
  assert(vector != NULL);
  assert(element != NULL);

  if (_vector_should_grow(vector)) {
    if (_vector_adjust_capacity(vector) == VECTOR_ERROR) {
      return VECTOR_ERROR;
    }
  }

  _vector_assign(vector, vector->size, element);

  ++vector->size;

  return VECTOR_SUCCESS;
}

int aom_vector_push_front(Vector *vector, void *element) {
  return aom_vector_insert(vector, 0, element);
}

int aom_vector_insert(Vector *vector, size_t index, void *element) {
  void *offset;

  assert(vector != NULL);
  assert(element != NULL);
  assert(index <= vector->size);

  if (vector == NULL) return VECTOR_ERROR;
  if (element == NULL) return VECTOR_ERROR;
  if (vector->element_size == 0) return VECTOR_ERROR;
  if (index > vector->size) return VECTOR_ERROR;

  if (_vector_should_grow(vector)) {
    if (_vector_adjust_capacity(vector) == VECTOR_ERROR) {
      return VECTOR_ERROR;
    }
  }

  /* Move other elements to the right */
  if (_vector_move_right(vector, index) == VECTOR_ERROR) {
    return VECTOR_ERROR;
  }

  /* Insert the element */
  offset = _vector_offset(vector, index);
  memcpy(offset, element, vector->element_size);
  ++vector->size;

  return VECTOR_SUCCESS;
}

int aom_vector_assign(Vector *vector, size_t index, void *element) {
  assert(vector != NULL);
  assert(element != NULL);
  assert(index < vector->size);

  if (vector == NULL) return VECTOR_ERROR;
  if (element == NULL) return VECTOR_ERROR;
  if (vector->element_size == 0) return VECTOR_ERROR;
  if (index >= vector->size) return VECTOR_ERROR;

  _vector_assign(vector, index, element);

  return VECTOR_SUCCESS;
}

/* Deletion */
int aom_vector_pop_back(Vector *vector) {
  assert(vector != NULL);
  assert(vector->size > 0);

  if (vector == NULL) return VECTOR_ERROR;
  if (vector->element_size == 0) return VECTOR_ERROR;

  --vector->size;

#ifndef VECTOR_NO_SHRINK
  if (_vector_should_shrink(vector)) {
    _vector_adjust_capacity(vector);
  }
#endif

  return VECTOR_SUCCESS;
}

int aom_vector_pop_front(Vector *vector) { return aom_vector_erase(vector, 0); }

int aom_vector_erase(Vector *vector, size_t index) {
  assert(vector != NULL);
  assert(index < vector->size);

  if (vector == NULL) return VECTOR_ERROR;
  if (vector->element_size == 0) return VECTOR_ERROR;
  if (index >= vector->size) return VECTOR_ERROR;

  /* Just overwrite */
  _vector_move_left(vector, index);

#ifndef VECTOR_NO_SHRINK
  if (--vector->size == vector->capacity / 4) {
    _vector_adjust_capacity(vector);
  }
#endif

  return VECTOR_SUCCESS;
}

int aom_vector_clear(Vector *vector) { return aom_vector_resize(vector, 0); }

/* Lookup */
void *aom_vector_get(Vector *vector, size_t index) {
  assert(vector != NULL);
  assert(index < vector->size);

  if (vector == NULL) return NULL;
  if (vector->element_size == 0) return NULL;
  if (index >= vector->size) return NULL;

  return _vector_offset(vector, index);
}

const void *aom_vector_const_get(const Vector *vector, size_t index) {
  assert(vector != NULL);
  assert(index < vector->size);

  if (vector == NULL) return NULL;
  if (vector->element_size == 0) return NULL;
  if (index >= vector->size) return NULL;

  return _vector_const_offset(vector, index);
}

void *aom_vector_front(Vector *vector) { return aom_vector_get(vector, 0); }

void *aom_vector_back(Vector *vector) {
  return aom_vector_get(vector, vector->size - 1);
}

/* Information */

bool aom_vector_is_initialized(const Vector *vector) {
  return vector->data != NULL;
}

size_t aom_vector_byte_size(const Vector *vector) {
  return vector->size * vector->element_size;
}

size_t aom_vector_free_space(const Vector *vector) {
  return vector->capacity - vector->size;
}

bool aom_vector_is_empty(const Vector *vector) { return vector->size == 0; }

/* Memory management */
int aom_vector_resize(Vector *vector, size_t new_size) {
  if (new_size <= vector->capacity * VECTOR_SHRINK_THRESHOLD) {
    vector->size = new_size;
    if (_vector_reallocate(vector, new_size * VECTOR_GROWTH_FACTOR) == -1) {
      return VECTOR_ERROR;
    }
  } else if (new_size > vector->capacity) {
    if (_vector_reallocate(vector, new_size * VECTOR_GROWTH_FACTOR) == -1) {
      return VECTOR_ERROR;
    }
  }

  vector->size = new_size;

  return VECTOR_SUCCESS;
}

int aom_vector_reserve(Vector *vector, size_t minimum_capacity) {
  if (minimum_capacity > vector->capacity) {
    if (_vector_reallocate(vector, minimum_capacity) == VECTOR_ERROR) {
      return VECTOR_ERROR;
    }
  }

  return VECTOR_SUCCESS;
}

int aom_vector_shrink_to_fit(Vector *vector) {
  return _vector_reallocate(vector, vector->size);
}

/* Iterators */
Iterator aom_vector_begin(Vector *vector) { return aom_vector_iterator(vector, 0); }

Iterator aom_vector_end(Vector *vector) {
  return aom_vector_iterator(vector, vector->size);
}

Iterator aom_vector_iterator(Vector *vector, size_t index) {
  Iterator iterator = { NULL, 0 };

  assert(vector != NULL);
  assert(index <= vector->size);

  if (vector == NULL) return iterator;
  if (index > vector->size) return iterator;
  if (vector->element_size == 0) return iterator;

  iterator.pointer = _vector_offset(vector, index);
  iterator.element_size = vector->element_size;

  return iterator;
}

void *aom_iterator_get(Iterator *iterator) { return iterator->pointer; }

int aom_iterator_erase(Vector *vector, Iterator *iterator) {
  size_t index = aom_iterator_index(vector, iterator);

  if (aom_vector_erase(vector, index) == VECTOR_ERROR) {
    return VECTOR_ERROR;
  }

  *iterator = aom_vector_iterator(vector, index);

  return VECTOR_SUCCESS;
}

void aom_iterator_increment(Iterator *iterator) {
  assert(iterator != NULL);
  // iterator->pointer += iterator->element_size;
  iterator->pointer =
      (unsigned char *)iterator->pointer + iterator->element_size;
}

void aom_iterator_decrement(Iterator *iterator) {
  assert(iterator != NULL);
  // iterator->pointer -= iterator->element_size;
  iterator->pointer =
      (unsigned char *)iterator->pointer - iterator->element_size;
}

void *aom_iterator_next(Iterator *iterator) {
  void *current = iterator->pointer;
  aom_iterator_increment(iterator);

  return current;
}

void *aom_iterator_previous(Iterator *iterator) {
  void *current = iterator->pointer;
  aom_iterator_decrement(iterator);

  return current;
}

bool aom_iterator_equals(Iterator *first, Iterator *second) {
  assert(first->element_size == second->element_size);
  return first->pointer == second->pointer;
}

bool aom_iterator_is_before(Iterator *first, Iterator *second) {
  assert(first->element_size == second->element_size);
  return first->pointer < second->pointer;
}

bool aom_iterator_is_after(Iterator *first, Iterator *second) {
  assert(first->element_size == second->element_size);
  return first->pointer > second->pointer;
}

size_t aom_iterator_index(Vector *vector, Iterator *iterator) {
  assert(vector != NULL);
  assert(iterator != NULL);
  // return (iterator->pointer - vector->data) / vector->element_size;
  return ((unsigned char *)iterator->pointer - (unsigned char *)vector->data) /
         vector->element_size;
}
