#include "arc/console/shell.h"

#include "arc/console/buffer.h"
#include "arc/std/string.h"
#include "arc/std/vector.h"
#include <stdlib.h>

void ARC_ConsoleShell_Create(ARC_ConsoleShell **shell, ARC_ConsoleView *view, ARC_ConsoleShell_UpdateFn updateFn){
    *shell = (ARC_ConsoleShell *)malloc(sizeof(ARC_ConsoleShell));

    (*shell)->view = view;
    ARC_ConsoleBuffer_Create(&((*shell)->buffer));
    (*shell)->bufferLineIndex = 0;

    ARC_Vector_Create(&((*shell)->history));
    (*shell)->historyIndex = 0;

    (*shell)->updateFn = updateFn;
    (*shell)->currentLine = NULL;
    (*shell)->userInput = NULL;
}

void ARC_ConsoleShell_Destroy(ARC_ConsoleShell *shell){
    ARC_ConsoleBuffer_Destroy(shell->buffer);

    for(uint32_t i = 0; i < ARC_Vector_Size(shell->history); i++){
        ARC_String *temp = (ARC_String *)ARC_Vector_Get(shell->history, i);

        if(temp != NULL){
            ARC_String_Destroy(temp);
        }
    }

    ARC_Vector_Destroy(shell->history);
    free(shell);
}

void ARC_ConsoleShell_Update(ARC_ConsoleShell *shell){
    shell->updateFn(shell);
}

void ARC_ConsoleShell_Render(ARC_ConsoleShell *shell){
    ARC_ConsoleBuffer_Render(shell->buffer, shell->view);
}

void ARC_ConsoleShell_AddHistory(ARC_ConsoleShell *shell, ARC_String *string){
    ARC_Vector_Add(shell->history, (void *)string);
}

ARC_String *ARC_ConsoleShell_GetHistoryAt(ARC_ConsoleShell *shell, uint32_t index){
    uint32_t maxHistory = ARC_Vector_Size(shell->history);
    if(index >= maxHistory){
        return NULL;
    }

    return (ARC_String *)ARC_Vector_Get(shell->history, (maxHistory - 1) - index);
}
