#include "libublsettings.h"

#define locales_path "/usr/share/i18n/locales/"

yon_hash *locales_hash_table = NULL;

struct yon_locale {
    char *code;
    char *lang_ab;
    char *territory;
    char *language;
    char *lang_name;
    char *title;
};

struct yon_locale *yon_lang_new(){
    struct yon_locale *cur_locale = malloc(sizeof(struct yon_locale));
    memset(cur_locale,0,sizeof(struct yon_locale));
    return cur_locale;
}

char *yon_locale_unwrap(char *parameter){
    char *final = yon_char_new(parameter);
    free(yon_char_divide_search(final,"\"",-1));
    char *temp = yon_char_divide_search(final,"\"",-1);
    free(final);
    final = yon_char_return_if_exist(temp,NULL);
    return final;
}

void yon_locale_set(struct  yon_locale *target,char *locale_name){
    int size;
    char *path = yon_char_unite(locales_path,locale_name,NULL);
    config_str locale_string = yon_file_open(path,&size);
    target->code = yon_char_unite(locale_name,".UTF-8",NULL);
    target->lang_ab = yon_char_new(locale_name);
    target->territory = yon_char_parsed_check_exist_begins_with(locale_string,size,"territory");
    target->language = yon_char_parsed_check_exist_begins_with(locale_string,size,"language");
    target->lang_name = yon_char_parsed_check_exist_begins_with(locale_string,size,"lang_name");
    target->title = yon_char_parsed_check_exist_begins_with(locale_string,size,"title");
    if (!yon_char_is_empty(target->lang_ab)){
        char *temp = strstr(target->lang_ab,"_");
        if (!yon_char_is_empty(temp)) temp[0]='\0';
    }
    if (!yon_char_is_empty(target->territory)){
        char *temp = yon_locale_unwrap(target->territory);
        free(target->territory);
        target->territory = yon_char_new(temp);
    }
    if (!yon_char_is_empty(target->language)){
        char *temp = yon_locale_unwrap(target->language);
        free(target->language);
        target->language = yon_char_new(temp);
    }
    if (!yon_char_is_empty(target->lang_name)){
        char *temp = yon_locale_unwrap(target->lang_name);
        free(target->lang_name);
        target->lang_name = yon_char_new(temp);
    }
    if (!yon_char_is_empty(target->title)){
        char *temp = yon_locale_unwrap(target->title);
        free(target->title);
        target->title = yon_char_new(temp);
    }
    // yon_char_parsed_free(locale_string,size);
    free(path);
}

void yon_locale_init(){
    int size;
    config_str locales_list = yon_file_ls(locales_path,&size);
    locales_hash_table = yon_hash_new(size*2,yon_str_hash);
    for (int i=0;i<size;i++){
        if (!strcmp(locales_list[i],".")||!strcmp(locales_list[i],"..")) continue;
        struct yon_locale *cur_locale = yon_lang_new();
        yon_locale_set(cur_locale,locales_list[i]);
        yon_hash_insert(locales_hash_table,yon_char_new(locales_list[i]),cur_locale);
    }
    yon_char_parsed_free(locales_list,size);
}

config_str yon_locale_get_all_codes(int *size){
    (*size)=0;
    config_str final = NULL;
    for (int i=0;i<locales_hash_table->size;i++){
        if (locales_hash_table->data[i]){
            yon_hash_element *dict = NULL;
            for_dictionaries(dict,locales_hash_table->data[i]){
                yon_char_parsed_add_or_create_if_exists(final,size,dict->key);
            }
        }
    }
    return final;
}

char *yon_locale_get_parameter(char *code,enum YON_LOCALE_PARAMETER type){
    unsigned int hash = locales_hash_table->hash_func(code)%locales_hash_table->size;
    yon_hash_element *data = (yon_hash_element*)yon_dictionary_get((dictionary**)&locales_hash_table->data[hash],code);
    struct yon_locale *cur_locale = yon_dictionary_get_data(data,struct yon_locale*);
    switch(type){
        case YON_LOCALE_LANGUAGE:{
            return cur_locale->language;
        }break;
        case YON_LOCALE_LANG_NAME:{
            return cur_locale->lang_name;
        }break;
        case YON_LOCALE_TERRITORY:{
            return cur_locale->territory;
        }break;
        case YON_LOCALE_LANG_AB:{
            return cur_locale->lang_ab;
        }break;
        case YON_LOCALE_TITLE:{
            return cur_locale->title;
        }break;
        case YON_LOCALE_CODE:{
            return cur_locale->code;
        }break;
        
    }
}