#include <cstddef>
#include <cstdlib>

#include "vtr_assert.h"
#include "vtr_list.h"
#include "vtr_memory.h"
#include "vtr_error.h"
#include "vtr_util.h"

#ifndef __GLIBC__
	#include <stdlib.h>
#else
	#include <malloc.h>
#endif


namespace vtr {


#ifndef __GLIBC__
int malloc_trim(size_t /*pad*/) {
    return 0;
}
#else
int malloc_trim(size_t pad) {
    return ::malloc_trim(pad);
}
#endif

void* free(void *some){
	if(some){
		std::free(some);
		some = nullptr;
	}
	return nullptr;
}

void* calloc(size_t nelem, size_t size) {
	void *ret;
	if (nelem == 0) {
		return nullptr ;
	}

	if ((ret = std::calloc(nelem, size)) == nullptr ) {
		throw VtrError("Unable to calloc memory.", __FILE__, __LINE__);
	}
	return (ret);
}

void* malloc(size_t size) {
	void *ret;
	if (size == 0) {
		return nullptr ;
	}

	if ((ret = std::malloc(size)) == nullptr && size != 0) {
		throw VtrError("Unable to malloc memory.", __FILE__, __LINE__);
	}
	return (ret);
}

void* realloc(void *ptr, size_t size) {
	void *ret;

	ret = std::realloc(ptr, size);
	if (nullptr == ret && size != 0) {
		throw VtrError(string_fmt("Unable to realloc memory (ptr=%p, size=%d).", ptr, size),
                        __FILE__, __LINE__);
	}
	return (ret);
}

void* chunk_malloc(size_t size, t_chunk *chunk_info) {

	/* This routine should be used for allocating fairly small data             *
	 * structures where memory-efficiency is crucial.  This routine allocates   *
	 * large "chunks" of data, and parcels them out as requested.  Whenever     *
	 * it mallocs a new chunk it adds it to the linked list pointed to by       *
	 * chunk_info->chunk_ptr_head.  This list can be used to free the	    *
	 * chunked memory.							    *
	 * Information about the currently open "chunk" must be stored by the       *
	 * user program.  chunk_info->mem_avail_ptr points to an int storing	    *
	 * how many bytes are left in the current chunk, while			    *
	 * chunk_info->next_mem_loc_ptr is the address of a pointer to the	    *
	 * next free bytes in the chunk.  To start a new chunk, simply set	    *
	 * chunk_info->mem_avail_ptr = 0.  Each independent set of data		    *
	 * structures should use a new chunk.                                       */

	/* To make sure the memory passed back is properly aligned, I must *
	 * only send back chunks in multiples of the worst-case alignment  *
	 * restriction of the machine.  On most machines this should be    *
	 * a long, but on 64-bit machines it might be a long long or a     *
	 * double.  Change the typedef below if this is the case.          */

	typedef size_t Align;

    constexpr int CHUNK_SIZE = 32768;
    constexpr int FRAGMENT_THRESHOLD = 100;

	char *tmp_ptr;
	int aligned_size;

	VTR_ASSERT(chunk_info->mem_avail >= 0);

	if ((size_t) (chunk_info->mem_avail) < size) { /* Need to malloc more memory. */
		if (size > CHUNK_SIZE) { /* Too big, use standard routine. */
			tmp_ptr = (char *) vtr::malloc(size);

			/* When debugging, uncomment the code below to see if memory allocation size */
			/* makes sense */
			//#ifdef DEBUG
			// vtr_printf("NB: my_chunk_malloc got a request for %d bytes.\n", size);
			// vtr_printf("You should consider using vtr::malloc for such big requests.\n");
			// #endif

			VTR_ASSERT(chunk_info != nullptr);
			chunk_info->chunk_ptr_head = insert_in_vptr_list(
					chunk_info->chunk_ptr_head, tmp_ptr);
			return (tmp_ptr);
		}

		if (chunk_info->mem_avail < FRAGMENT_THRESHOLD) { /* Only a small scrap left. */
			chunk_info->next_mem_loc_ptr = (char *) vtr::malloc(CHUNK_SIZE);
			chunk_info->mem_avail = CHUNK_SIZE;
			VTR_ASSERT(chunk_info != nullptr);
			chunk_info->chunk_ptr_head = insert_in_vptr_list(
					chunk_info->chunk_ptr_head, chunk_info->next_mem_loc_ptr);
		}

		/* Execute else clause only when the chunk we want is pretty big,  *
		 * and would leave too big an unused fragment.  Then we use malloc *
		 * to allocate normally.                                           */

		else {
			tmp_ptr = (char *) vtr::malloc(size);
			VTR_ASSERT(chunk_info != nullptr);
			chunk_info->chunk_ptr_head = insert_in_vptr_list(
					chunk_info->chunk_ptr_head, tmp_ptr);
			return (tmp_ptr);
		}
	}

	/* Find the smallest distance to advance the memory pointer and keep *
	 * everything aligned.                                               */

	if (size % sizeof(Align) == 0) {
		aligned_size = size;
	} else {
		aligned_size = size + sizeof(Align) - size % sizeof(Align);
	}

	tmp_ptr = chunk_info->next_mem_loc_ptr;
	chunk_info->next_mem_loc_ptr += aligned_size;
	chunk_info->mem_avail -= aligned_size;
	return (tmp_ptr);
}

void free_chunk_memory(t_chunk *chunk_info) {

	/* Frees the memory allocated by a sequence of calls to my_chunk_malloc. */

	t_linked_vptr *curr_ptr, *prev_ptr;

	curr_ptr = chunk_info->chunk_ptr_head;

	while (curr_ptr != nullptr ) {
		free(curr_ptr->data_vptr); /* Free memory "chunk". */
		prev_ptr = curr_ptr;
		curr_ptr = curr_ptr->next;
		free(prev_ptr); /* Free memory used to track "chunk". */
	}
	chunk_info->chunk_ptr_head = nullptr;
	chunk_info->mem_avail = 0;
	chunk_info->next_mem_loc_ptr = nullptr;
}

} //namespace
