#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

char *error_buff = NULL;
char *error_secondary_buff = NULL;

int error_buff_counter = 0;

void diot_error_clear(void)
{
    if (error_buff) {
	free(error_buff);
	error_buff = NULL;
    }
    error_buff_counter = 0;
}

void diot_error_secondary_buff_clear(void)
{
    if (error_secondary_buff) {
	free(error_secondary_buff);
	error_secondary_buff = NULL;
    }
}


void diot_error_print(void)
{
    printf("ERRORS:\n");
    if (error_buff)
	printf("%s", error_buff);
    else
	printf("None\n");
}

void diot_error_add(const char* format, ...)
{
    char *new_error_buff;
    char *err_str;
    int extra_len = 0;
    va_list args;

    /* check the length of error message */
    va_start(args, format);
    extra_len = vsnprintf(NULL, 0, format, args);
    va_end(args);

    err_str = (char *) malloc(extra_len + 1);

    /* fill the error message */
    va_start(args, format);
    vsprintf(err_str, format, args);
    va_end(args);

    if (!error_buff) {
        new_error_buff = (char *) malloc(extra_len + 1);
        sprintf(new_error_buff, "%s", err_str);
    } else {
        new_error_buff = (char *) malloc(strlen(error_buff) + extra_len + 1);
        sprintf(new_error_buff, "%s%s", error_buff, err_str);
        free(error_buff);
    }
    error_buff = new_error_buff;
    free(err_str);
    error_buff_counter++;
}

int diot_error_buff_n_errors(void)
{
    return error_buff_counter;
}

void diot_error_add_to_secondary_buff(void)
{
    char *new_error_buff;
    int new_len;

    if (!error_secondary_buff) {
	/* error_secondary_buff is null, malloc 1 byte for '\0' */
	error_secondary_buff = (char *) malloc(1);
	error_secondary_buff[0] = '\0';
    }

    if (!error_buff) {
	/* error_buff is null, malloc 1 byte for '\0' */
	error_buff = (char *) malloc(1);
	error_buff[0] = '\0';
    }

    new_len = strlen(error_secondary_buff) + strlen(error_buff);
    new_error_buff = (char *) malloc(new_len + 1);

    /* copy error_buff to error_secondary_buff */
    sprintf(new_error_buff, "%s%s", error_secondary_buff, error_buff);

    free(error_buff);
    error_buff = NULL;
    free(error_secondary_buff);
    error_secondary_buff = new_error_buff;

    error_buff_counter = 0;
}

void diot_error_move_from_secondary_buff(void)
{
    if (error_buff)
	free(error_buff);

    error_buff = error_secondary_buff;
    error_secondary_buff = NULL;
}
