#include "ubl-settings-fstecadvised.h"

test_row_element *yon_test_row_element_new(){
    test_row_element *element = malloc(sizeof(test_row_element));
    memset(element,0,sizeof(test_row_element));
    GtkBuilder *builder = gtk_builder_new_from_resource(glade_path_test_element);
    element->TestRow = yon_gtk_builder_get_widget(builder,"TestRow");
    element->TestNameLabel = yon_gtk_builder_get_widget(builder,"TestNameLabel");
    element->TestSeparator = yon_gtk_builder_get_widget(builder,"TestSeparator");
    element->TestStatusLabel = yon_gtk_builder_get_widget(builder,"TestStatusLabel");
    g_object_set_data(G_OBJECT(element->TestRow),"test_row_element",element);
    gtk_widget_set_margin_start(gtk_widget_get_parent(element->TestNameLabel),15);

    return element;
}

void yon_row_element_append(main_window *widgets, char *test_name, char *status ){
    test_row_element *element = yon_test_row_element_new();
    gtk_list_box_insert(GTK_LIST_BOX(widgets->TestListbox),element->TestRow,-1);
    gtk_label_set_text(GTK_LABEL(element->TestNameLabel),_(test_name));

    if (!yon_char_is_empty(status)){
        if (!strcmp(status,"Failed")){
            gtk_style_context_add_class(gtk_widget_get_style_context(element->TestStatusLabel),"fail_text");
        } else if (!strcmp(status,"Success")) {
            gtk_style_context_add_class(gtk_widget_get_style_context(element->TestStatusLabel),"success_text");
        }
    }
    gtk_label_set_text(GTK_LABEL(element->TestStatusLabel),_(status));
}

test_row_element *yon_test_row_element_title_new(){
    test_row_element *element = malloc(sizeof(test_row_element));
    memset(element,0,sizeof(test_row_element));
    GtkBuilder *builder = gtk_builder_new_from_resource(glade_path_test_element);
    element->TestRow = yon_gtk_builder_get_widget(builder,"TestRow");
    element->TestNameLabel = yon_gtk_builder_get_widget(builder,"TestNameLabel");
    element->TestSeparator = yon_gtk_builder_get_widget(builder,"TestSeparator");
    element->TestStatusLabel = yon_gtk_builder_get_widget(builder,"TestStatusLabel");
    g_object_set_data(G_OBJECT(element->TestRow),"test_row_element",element);
    gtk_widget_hide(element->TestStatusLabel);
    gtk_widget_hide(element->TestSeparator);

    return element;
}

void yon_row_element_append_title(main_window *widgets, char *test_name ){
    test_row_element *element = yon_test_row_element_title_new();
    gtk_style_context_add_class(gtk_widget_get_style_context(element->TestRow),"bggrey");
    gtk_list_box_insert(GTK_LIST_BOX(widgets->TestListbox),element->TestRow,-1);
    char *title_name = yon_char_unite("<b>",_(test_name),"</b>",NULL);
    gtk_label_set_markup(GTK_LABEL(element->TestNameLabel),title_name);
}

void yon_test_clear(main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->TestListbox));
    GList *iter;
    for (iter=list;iter;iter=iter->next){
        gtk_widget_destroy(GTK_WIDGET(iter->data));
    }
    g_list_free(list);
}

void yon_test_tab_resize(main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->TestListbox));
    GList *iter;
    gint width = 0;
    for (iter=list;iter;iter=iter->next){
        test_row_element *element = g_object_get_data(G_OBJECT(iter->data),"test_row_element");
        gint natural_width=0;
        gtk_widget_get_preferred_width(GTK_WIDGET(element->TestNameLabel),NULL,&natural_width);
        if (gtk_widget_get_visible(element->TestStatusLabel)&&width<natural_width) width = natural_width;
    }
    for (iter=list;iter;iter=iter->next){
        test_row_element *element = g_object_get_data(G_OBJECT(iter->data),"test_row_element");
        if (gtk_widget_get_visible(element->TestStatusLabel)){
            gtk_widget_set_size_request(GTK_WIDGET(element->TestNameLabel),width,-1);
        }
    }
}


struct test_struct *yon_test_get_struct(char *testline){
    struct test_struct *final = malloc(sizeof(struct test_struct));
    memset(final,0,sizeof(struct test_struct));

    int parsed_size;
    config_str parsed = yon_char_parse(testline,&parsed_size,";");
    if (parsed_size==4){
        final->group = yon_char_new(parsed[2]);
        final->test_name = yon_char_new(parsed[3]);
        final->test_status = yon_char_new(parsed[1]);
        if (!yon_char_is_empty(final->test_status)){
            yon_char_remove_last_symbol(final->test_status,']');
            if (final->test_status[0]=='[') free(yon_char_divide_search(final->test_status,"[",-1));
            final->test_status[0] = g_ascii_toupper(final->test_status[0]);
        }
    } else if (parsed_size==3){
        final->group = yon_char_new(parsed[1]);
        final->test_name = yon_char_new(parsed[2]);
    }
    yon_char_parsed_free(parsed,parsed_size);
    return final;
}

void yon_test_parse(struct idle_struct *temp_struct){
    main_window *widgets = temp_struct->widgets;;
    config_str test_result = temp_struct->test_result;
    int size = temp_struct->size;
    yon_test_clear(widgets);
    dictionary *test_groups = NULL;
    for (int i=1;i<size;i++){
        yon_char_remove_last_symbol(test_result[i],'\n');
        struct test_struct *cur_test = yon_test_get_struct(test_result[i]);
        dictionary *cur = yon_dictionary_get(&test_groups,cur_test->group);
        if (!cur){
            yon_dictionary_add_or_create_if_exists_with_data(test_groups,cur_test->group,yon_dictionary_new_with_data(NULL,cur_test));
        } else {
            dictionary* cur_subdict = cur->data;
            yon_dictionary_add_or_create_if_exists_with_data(cur_subdict,NULL,cur_test);
        }

    }
    dictionary *dict;
    yon_row_element_append(widgets,NAME_LABEL,STATUS_LABEL);
    {
        GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->TestListbox));
        test_row_element *element = g_object_get_data(G_OBJECT(list->data),"test_row_element");
        gtk_widget_set_margin_start(gtk_widget_get_parent(element->TestNameLabel),0);
        gtk_widget_set_margin_end(element->TestNameLabel,15);
        g_list_free(list);
    }
    for_dictionaries(dict,test_groups){
            dictionary *sub_dict = (dictionary*)dict->data;
            yon_row_element_append_title(widgets,dict->key);
            dictionary *dact;
            for_dictionaries(dact,sub_dict){
                struct test_struct *test_element = (struct test_struct*)dact->data;
                yon_row_element_append(widgets,test_element->test_name,test_element->test_status);

            }
    }
    gtk_widget_hide(widgets->LoadingSpinner);
    yon_test_tab_resize(widgets);
    yon_char_parsed_free(test_result,size);
}

void *yon_test_start(main_window *widgets);
void *yon_test_list(main_window *widgets);
void on_test_start(GtkWidget *, main_window *widgets);
void yon_startup_tests_list(main_window *widgets);

void *yon_test_start(main_window *widgets){
    char *command = NULL;
    char * fstec_apply_parameter = config(FSTEC_parameter);
    if (!yon_char_is_empty(fstec_apply_parameter)&&!strcmp(fstec_apply_parameter,"enable")){
        command = fstec_test_apply_command;
    } else {
        command = fstec_test_command;
    }
    int size;
    config_str test_result = yon_config_load(yon_debug_output("%s\n",command), &size);
    struct idle_struct *temp_struct = malloc(sizeof(struct idle_struct));
    temp_struct->widgets = widgets;
    temp_struct->test_result = test_result;
    temp_struct->size = size;
    g_idle_add_once((GSourceOnceFunc)yon_test_parse,temp_struct);
    return NULL;
}

void *yon_test_list(main_window *widgets){
    int size;
    config_str test_result = yon_config_load(fstec_list_command, &size);
    struct idle_struct *temp_struct = malloc(sizeof(struct idle_struct));
    temp_struct->widgets = widgets;
    temp_struct->test_result = test_result;
    temp_struct->size = size;
    g_idle_add_once((GSourceOnceFunc)yon_test_parse,temp_struct);
    return NULL;
}

void on_test_start(GtkWidget *, main_window *widgets){
    g_thread_new("test_thread",(GThreadFunc)yon_test_start,widgets);
    gtk_widget_show(widgets->LoadingSpinner);
}

void yon_startup_tests_list(main_window *widgets){
    g_thread_new("test_thread",(GThreadFunc)yon_test_list,widgets);
    gtk_widget_show(widgets->LoadingSpinner);
}
