#include "controller_tests.h"
#include "../controller/controller.h"
#include "../domain/domain.h"
#include "../repository/repository.h"
#include "../undo_module/undo_controller/undo_controller.h"
#include "../undo_module/function_call/functioncall.h"
#include "../undo_module/operation/operation.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void controller_tests(void){
    printf("Running controller tests\n");
    Repository* repository = _Repository_Constructor();
    UndoController* undo_controller = _UndoController_Constructor();
    Controller* controller = _Controller_Constructor(repository,undo_controller);
    char* name;
    char* supplier;
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Water");
    strcpy(supplier,"Bucovina");
    _Controller_add(controller,name,supplier,20,2,3,2025);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Water");
    strcpy(supplier,"Dorna");
    _Controller_add(controller,name,supplier,5,16,10,2026);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Flour");
    strcpy(supplier,"Boromir");
    _Controller_add(controller,name,supplier,25,16,10,2023);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Flour");
    strcpy(supplier,"Titan");
    _Controller_add(controller,name,supplier,25,4,1,2023);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Sugar");
    strcpy(supplier,"Margarita");
    _Controller_add(controller,name,supplier,25,7,11,2021);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Sugar");
    strcpy(supplier,"Diamant");
    _Controller_add(controller,name,supplier,125,23,10,2021);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Rum Extract");
    strcpy(supplier,"Diamant");
    _Controller_add(controller,name,supplier,65,23,10,2021);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Vanilla Extract");
    strcpy(supplier,"Diamant");
    _Controller_add(controller,name,supplier,45,23,10,2025);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Apples");
    strcpy(supplier,"Eco Fruits");
    _Controller_add(controller,name,supplier,95,4,9,2021);
    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Plums");
    strcpy(supplier,"Eco Fruits");
    _Controller_add(controller,name,supplier,15,22,11,2021);

    assert(_Controller_getLenght(controller) == 10);
    assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
    assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Bucovina") == 0);
    assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 20);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 2);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 2);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2025);

    assert(strcmp(_Material_GetName(_Controller_getItem(controller,9)),"Plums" ) == 0);
    assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,9)),"Eco Fruits" ) == 0);
    assert(_Material_GetQuantity(_Controller_getItem(controller,9)) == 15);
    assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mday == 22);
    assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mon == 10);
    assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_year == 2021);

    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Water");
    strcpy(supplier,"Bucovina");

    _Controller_update(controller,name,supplier,30,2,3,2025);
    assert(_Controller_getLenght(controller) == 10);
    assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
    assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Bucovina") == 0);
    assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 30);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 2);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 2);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2025);

    name = (char*)malloc(255);
    supplier = (char*)malloc(255);
    strcpy(name,"Water");
    strcpy(supplier,"Bucovina");
    _Controller_delete(controller,name,supplier,2,3,2025);
    assert(_Controller_getLenght(controller) == 9);
    assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
    assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Dorna") == 0);
    assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 5);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 16);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 9);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2026);

    _Controller_undo(controller);
    assert(_Controller_getLenght(controller) == 10);
    assert(strcmp(_Material_GetName(_Controller_getItem(controller,9)), "Water") == 0);
    assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,9)), "Bucovina") == 0);
    assert(_Material_GetQuantity(_Controller_getItem(controller,9)) == 30);
    assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mday == 2);
    assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mon == 2);
    assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_year == 2025);

    _Controller_redo(controller);
    assert(_Controller_getLenght(controller) == 9);
    assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
    assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Dorna") == 0);
    assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 5);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 16);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 9);
    assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2026);

    _Controller_Destructor(controller);


}