#include "buffer.h"
#include <string.h>

ByteBuffer* buffer_create(size_t initial_capacity) {
    ByteBuffer* buf = malloc(sizeof(ByteBuffer));
    if (!buf) return NULL;

    buf->data = malloc(initial_capacity);
    if (!buf->data) {
        free(buf);
        return NULL;
    }

    buf->size = 0;
    buf->capacity = initial_capacity;
    return buf;
}

void buffer_destroy(ByteBuffer* buf) {
    if (!buf) return;
    free(buf->data);
    free(buf);
}

bool buffer_append(ByteBuffer* buf, const uint8_t* data, size_t len) {
    if (!buf || !data) return false;

    if (buf->size + len > buf->capacity) {
        size_t new_cap = (buf->size + len) * 2;
        uint8_t* new_data = realloc(buf->data, new_cap);
        if (!new_data) return false;
        buf->data = new_data;
        buf->capacity = new_cap;
    }

    memcpy(buf->data + buf->size, data, len);
    buf->size += len;
    return true;
}

bool buffer_resize(ByteBuffer* buf, size_t new_size) {
    if (!buf) return false;

    if (new_size > buf->capacity) {
        uint8_t* new_data = realloc(buf->data, new_size);
        if (!new_data) return false;
        buf->data = new_data;
        buf->capacity = new_size;
    }

    buf->size = new_size;
    return true;
}

void buffer_clear(ByteBuffer* buf) {
    if (buf) buf->size = 0;
}

StringArray* string_array_create(size_t initial_capacity) {
    StringArray* arr = malloc(sizeof(StringArray));
    if (!arr) return NULL;

    arr->items = malloc(sizeof(char*) * initial_capacity);
    if (!arr->items) {
        free(arr);
        return NULL;
    }

    arr->count = 0;
    arr->capacity = initial_capacity;
    return arr;
}

void string_array_destroy(StringArray* arr) {
    if (!arr) return;

    for (size_t i = 0; i < arr->count; i++) {
        free(arr->items[i]);
    }
    free(arr->items);
    free(arr);
}

bool string_array_add(StringArray* arr, const char* str) {
    if (!arr || !str) return false;

    if (arr->count >= arr->capacity) {
        size_t new_cap = arr->capacity * 2;
        char** new_items = realloc(arr->items, sizeof(char*) * new_cap);
        if (!new_items) return false;
        arr->items = new_items;
        arr->capacity = new_cap;
    }

    arr->items[arr->count] = _strdup(str);
    if (!arr->items[arr->count]) return false;
    arr->count++;
    return true;
}

bool string_array_contains(StringArray* arr, const char* str) {
    if (!arr || !str) return false;

    for (size_t i = 0; i < arr->count; i++) {
        if (strcmp(arr->items[i], str) == 0) {
            return true;
        }
    }
    return false;
}

ProfileList* profile_list_create(size_t initial_capacity) {
    ProfileList* list = malloc(sizeof(ProfileList));
    if (!list) return NULL;

    list->paths = malloc(sizeof(ProfilePath) * initial_capacity);
    if (!list->paths) {
        free(list);
        return NULL;
    }

    list->count = 0;
    list->capacity = initial_capacity;
    return list;
}

void profile_list_destroy(ProfileList* list) {
    if (!list) return;
    free(list->paths);
    free(list);
}

bool profile_list_add(ProfileList* list, const wchar_t* path) {
    if (!list || !path) return false;

    if (list->count >= list->capacity) {
        size_t new_cap = list->capacity * 2;
        ProfilePath* new_paths = realloc(list->paths, sizeof(ProfilePath) * new_cap);
        if (!new_paths) return false;
        list->paths = new_paths;
        list->capacity = new_cap;
    }

    wcsncpy_s(list->paths[list->count].path, MAX_PATH_LEN, path, _TRUNCATE);
    list->paths[list->count].is_valid = true;
    list->count++;
    return true;
}