#include "libublsettings-gtk3.h"

GHashTable *_apps = NULL;

apps *yon_app_new(){
    apps *new_app = malloc(sizeof(apps));
    memset(new_app,0,sizeof(apps));
    return new_app;
}

void yon_app_free(apps *target){
    if (!yon_char_is_empty(target->Comment)) free(target->Comment);
    if (!yon_char_is_empty(target->Exec)) free(target->Exec);
    if (!yon_char_is_empty(target->Icon)) free(target->Icon);
    if (target->categories_size) yon_char_parsed_free(target->Categories,target->categories_size);
}

int yon_app_set_from_file(apps *target, const char *path){
    GKeyFile *cur_file = g_key_file_new();
    GError *err = NULL;
    if (!g_key_file_load_from_file(cur_file,path,G_KEY_FILE_KEEP_TRANSLATIONS,&err)) {
        printf("%s\n",err->message);
        return 0;
    }

    target->Name = g_key_file_get_locale_string(cur_file,"Desktop Entry","Name",NULL,NULL);
    target->NameRaw = g_key_file_get_string(cur_file,"Desktop Entry","Name",NULL);
    target->Desktop_path = yon_char_new(path);
    target->Comment = g_key_file_get_string(cur_file,"Desktop Entry","Comment",NULL);
    char *categories = g_key_file_get_string(cur_file,"Desktop Entry","Categories",NULL);
    target->Categories = yon_char_parse(categories,&target->categories_size,";");
    target->Exec = g_key_file_get_string(cur_file,"Desktop Entry","Exec",NULL);
    target->Icon = g_key_file_get_string(cur_file,"Desktop Entry","Icon",NULL);
    char *pluggable = g_key_file_get_string(cur_file,"Desktop Entry","X-XfcePluggable",NULL);
    target->Pluggable = !yon_char_is_empty(pluggable)&&!strcmp(pluggable,"true");
    char *dual_pluggable = g_key_file_get_string(cur_file,"Desktop Entry","X-UBLPluggable",NULL);
    target->DualPluggable = !yon_char_is_empty(dual_pluggable)&&!strcmp(dual_pluggable,"true");
    char *type = g_key_file_get_string(cur_file,"Desktop Entry","Type",NULL);
    target->Type = !yon_char_is_empty(type)&&!strcmp(type,"Application");
    target->keywords = g_key_file_get_locale_string(cur_file,"Desktop Entry","Keywords",NULL,NULL);

    if (!yon_char_is_empty(target->Exec)&&strstr(target->Exec," ")){
        int parsed_size;
        config_str parsed = yon_char_parse(target->Exec,&parsed_size," ");
        for (int i=0;i<parsed_size;i++){
            if ((strlen(parsed[i])==2&&parsed[i][0]=='%')){
                free(parsed[i]);
                parsed[i] = yon_char_new(" ");
                parsed[i][0]='\0';
            }
        }
        free(target->Exec);
        target->Exec = yon_char_parsed_to_string(parsed,parsed_size," ");
    }

    free(categories);
    free(pluggable);
    free(dual_pluggable);
    free(type);
    return 1;
}

void yon_apps_init(){
    int size;
    config_str paths = yon_file_ls(DesktopPath,&size);
    _apps = g_hash_table_new_full(g_str_hash,g_str_equal,(GDestroyNotify)free,(GDestroyNotify)yon_app_free);

    for (int i=0;i<size;i++){
        if (!strstr(paths[i],".desktop")) continue;
        char *cur_path = yon_char_unite(DesktopPath,"/",paths[i],NULL);
        apps *cur_app = yon_app_new();
        if (yon_app_set_from_file(cur_app,cur_path)){
            g_hash_table_insert(_apps,yon_char_new(cur_app->Desktop_path),cur_app);
        }
    }
}

gboolean __yon_apps_uninit_remove(char *key, apps *value, void*){
    free(key);
    yon_app_free(value);

}

void yon_apps_uninit(){
    g_hash_table_destroy(_apps);
    _apps=NULL;
}

gboolean yon_apps_check_init(){
    return !!_apps;
}

apps *yon_apps_get(char *name){
    apps *cur_app = g_hash_table_lookup(_apps,name);
    if (cur_app){
        apps *ret_app = yon_app_new();
        memcpy(ret_app,cur_app,sizeof(apps));
        cur_app = ret_app;
    }
    return cur_app;
}

apps *yon_apps_find(char *name){
    guint size = 0;
    config_str keys = (config_str)g_hash_table_get_keys_as_array(_apps,&size);
    apps *cur_app = NULL;

    for (guint i=0;i<size;i++){
        if (strstr(keys[i],name)){
            cur_app = yon_apps_get(keys[i]);
            break;
        }
    }
    return cur_app;
}

config_str yon_apps_get_by_categories(config_str categories, int categories_size, int *final_size){
    (*final_size) = 0;
    GList *list = g_hash_table_get_values(_apps);
    if (!list) return NULL;
    config_str final = NULL; 
    GList *iter;
    for (iter=list;iter;iter=iter->next){
        apps *cur_app = (apps*)iter->data;
        if (yon_char_parsed_includes_char_parsed(cur_app->Categories,categories,cur_app->categories_size, categories_size)){
            yon_char_parsed_add_or_create_if_exists(final,final_size,cur_app->Desktop_path);
        }
    }
    return final;
}