#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include <locale.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <libintl.h>
#include <getopt.h>
#include <libintl.h>
#include <libublsettings.h>
#include <libublsettings-gtk3.h>
#include <libublsettingsui-gtk3.h>
#ifdef WEBKIT_FOUND
    #include <webkit2/webkit2.h>
#endif 
#include "ubl-strings.h"


#define _(String) gettext(String)

#define main_icon "com.ublinux.ubl-settings-system"
#define glade_path "/com/ublinux/ui/ubl-settings-system.glade"
#define glade_domain_path "/com/ublinux/ui/ubl-settings-system-domain.glade"
#define glade_connection_path "/com/ublinux/ui/ubl-settings-system-connection.glade"
#define glade_domain_view_path "/com/ublinux/ui/ubl-settings-system-domain-view.glade"
#define glade_locales_path "/com/ublinux/ui/ubl-settings-system-layouts.glade"
#define glade_domain_options_path "/com/ublinux/ui/ubl-settings-system-domain-options.glade"
#define CssPath "/com/ublinux/css/ubl-settings-system.css"
#define config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",LocaleName,"/",LocaleName,".conf",NULL)

#define LocalePath "/usr/share/locale" 
#define LocaleName "ubl-settings-system"

#define config_global_load_command "ubconfig --source global get "
#define config_local_load_command "ubconfig --source system get "

#define get_id_command "/etc/machine-id"

#define config_get_command(source) yon_char_unite("ubconfig --source ", source, " -ea get [system] HOSTNAME MACHINEID -- get [locale] CONSOLE_FONT LOCALE LANG -- get [network] DOMAIN DOMAIN[admanger] DOMAIN[server] DOMAIN[dns] DOMAIN[client]",NULL)
#define config_get_default_command "ubconfig --source default get [locale] CONSOLE_FONT LOCALE LANG -- [system] HOSTNAME"

#define config_get_global_only_parameters ""
#define config_get_local_only_parameters ""

// #define languages_command "while IFS= read -ru3 SELECT_LOCALE; do SELECT_LOCALE=\"${SELECT_LOCALE% *}\"; [[ $(< /usr/share/i18n/locales/${SELECT_LOCALE%.*}) =~ \"title\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"language\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"territory\"[[:blank:]]*\\\"([^\\\"]*)\\\" ]] && echo \"${BASH_REMATCH[2]}|${BASH_REMATCH[3]}|${SELECT_LOCALE}|${BASH_REMATCH[1]}\" || echo \"||${SELECT_LOCALE}|\"; done 3< \"/usr/share/i18n/SUPPORTED\""
#define languages_command "while IFS= read -ru3 SELECT_LOCALE; do SELECT_LOCALE=\"${SELECT_LOCALE% *}\"; [[ $(< /usr/share/i18n/locales/${SELECT_LOCALE%.*}) =~ (\"language\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"territory\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"country_name\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"lang_name\"[[:blank:]]*\\\"([^\\\"]*)\\\")|(\"language\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"territory\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"lang_name\"[[:blank:]]*\\\"([^\\\"]*)\\\")|(\"language\"[[:blank:]]*\\\"([^\\\"]*)\\\".*\"territory\"[[:blank:]]*\\\"([^\\\"]*)\\\") ]] && echo \"${SELECT_LOCALE}|${BASH_REMATCH[2]}${BASH_REMATCH[7]}${BASH_REMATCH[11]}${BASH_REMATCH[5]:+ (${BASH_REMATCH[5]})}${BASH_REMATCH[9]:+ (${BASH_REMATCH[9]})}|${BASH_REMATCH[3]}${BASH_REMATCH[8]}${BASH_REMATCH[12]}${BASH_REMATCH[4]:+ (${BASH_REMATCH[4]})}\" || echo \"${SELECT_LOCALE}\"; done 3< \"/usr/share/i18n/SUPPORTED\""

#define check_domain_access_command(targeet) yon_char_append("adcli info --domain ",target)
#define get_domain_info_command "ubdomain-client list "
#define domains_seek_command "ubdomain-client discover"
#define domain_connect_command(target,user,password, addition,ou,options) yon_char_unite("ubdomain-client join",\
!yon_char_is_empty(user)?" --user \"":"",!yon_char_is_empty(user)?user:"",!yon_char_is_empty(user)?"\"":"",\
!yon_char_is_empty(password)?" --password \"":"",!yon_char_is_empty(password)?password:"",!yon_char_is_empty(password)?"\"":"",\
" --domain \"",target,"\"",\
!yon_char_is_empty(ou)?" --ou \"":"",!yon_char_is_empty(ou)?ou:"",!yon_char_is_empty(ou)?"\"":"",\
!yon_char_is_empty(options)?" --authpam_opt \"":"",!yon_char_is_empty(options)?options:"",!yon_char_is_empty(options)?"\"":"",\
 addition,NULL) 
#define domain_disconnect_command(target,user,password) yon_char_unite("ubdomain-client leave",!yon_char_is_empty(user)?" --user \"":"",!yon_char_is_empty(user)?user:"",!yon_char_is_empty(user)?"\"":"",!yon_char_is_empty(password)?" --password \"":"",!yon_char_is_empty(password)?password:"",!yon_char_is_empty(password)?"\"":""," --domain \"",target,"\"",NULL) 
#define kerberos_addition_command(target) yon_char_unite(" --domain_server \"",target,"\"",NULL)
#define dns_addition_command(target) yon_char_unite(" --dns \"",target,"\"",NULL)
#define client_addition_command(target) yon_char_unite(" --domain_client \"",target,"\"",NULL)

#define sssd_client_parameters_command "authselect list-features sssd"
#define windbind_client_parameters_command "authselect list-features winbind"
#define samba_client_parameters_command "authselect list-features winbind"

#define domain_info(target) yon_char_unite("ubdomain-client discover --domain \"",target,"\"",NULL)

#define domain_connected_icon "com.ublinux.ubl-settings-system.plug-connected-symbolic"
#define domain_disconnected_icon "com.ublinux.ubl-settings-system.plug-disconnected-symbolic"
#define add_icon_path "com.ublinux.libublsettingsui-gtk3.increase-symbolic"
#define remove_icon_path "com.ublinux.libublsettingsui-gtk3.trash-symbolic"

#define domain_connect_check "ubdomain-client list|grep -q 'configured'"

#define domain_check_alive(target) yon_char_unite("timeout --kill-after=0.1 2 dig +time=1 +tries=1 +noall -t SRV _ldap._tcp.",target," @",target," &>/dev/null",NULL)

#define terminal_command_start(title,command) yon_char_unite("vte-2.91 --name=vte --cursor-shape=ibeam --cursor-blink=off --keep --no-pty --title=\"",title,"\" --no-shell --icon-title --no-context-menu --background-color='rgb(0,0,0)' --foreground-color='rgb(255,255,255)' --whole-window-transparent --no-geometry-hints -- ", command, NULL)

#define locale_parameter "LOCALE"
#define locale_parameter_command "ubconfig --source global get [locale] LOCALE"

#define hostname_parameter "HOSTNAME"
#define HOSTNAME_get_command "ubconfig --source global get [system] HOSTNAME"

#define id_parameter "MACHINEID"
#define MACHINEID_get_command "ubconfig --source global get [system] MACHINEID"

#define CONSOLE_FONT_get_command "ubconfig --source global get [locale] CONSOLE_FONT"

#define language_parameter "LANG"
#define language_parameter_command "ubconfig --source global get [locale] LANG"

#define DOMAIN "DOMAIN"
#define DOMAIN_ADMANGER "DOMAIN[admanger]"
#define DOMAIN_SERVER "DOMAIN[server]"
#define DOMAIN_DNS "DOMAIN[dns]"
#define DOMAIN_CLIENT "DOMAIN[client]"
#define DOMAIN_get_command "ubconfig --source global get [network] DOMAIN"

typedef char* string; 

__attribute__((unused)) static \
string version_application;


typedef struct {
    template_config_fields
    GtkListStore *localeslist;
    int save_config;
    int domain_connected;
    GMutex ThreadMutex;
    GHashTable *languages;
} config;
extern config main_config;

typedef struct {
    template_window_fields
    // Custom 
    GtkWidget *HostnameEntry;
    GtkWidget *IDCombo;
    GtkWidget *IDEntry;
    GtkWidget *IDCopyButton;
    GtkWidget *LocaleDefaultSwitch;
    GtkWidget *LocaleTree;
    GtkWidget *LocaleAddButton;
    GtkWidget *LocaleRemoveButton;
    GtkCellRenderer *LocaleCell;

    GtkWidget *DomainEntry;
    GtkWidget *DomainButton;
    GtkWidget *FindButton;

    GtkListStore *LanguageList;

    rmb_menu_window *locale_menu;

} main_window;


typedef struct {
    GtkWidget *Window;

    GtkWidget *HatText;
    GtkWidget *HeaderText;
    GtkWidget *InfoText;
    GtkWidget *AlwaysOpenCheck;

    GtkWidget *CancelButton;
    GtkWidget *AcceptButton;
} documentation_confirmation_window;

typedef struct {
    GtkWidget *Window;
    GtkWidget *StatusBox;
    GtkWidget *LanguagesTree;

    GtkWidget *CancelButton;
    GtkWidget *AcceptButton;
    GtkWidget *ManualEntry;
    GtkWidget *LoadingOverlay;
    GtkWidget *LoadingSpinner;
    GtkWidget *SearchEntry;
    GtkCellRenderer *ToggleCell;

    GtkListStore *LanguagesList;
    GtkTreeModel *LanguagesFilter;
} language_window;

typedef struct {
    GtkWidget *Window;

    GtkWidget *StatusBox;
    GtkWidget *HeadLabel;

    GtkWidget *CancelButton;
    GtkWidget *SaveButton;
    GtkWidget *AdressEntry;
    GtkWidget *LoginEntry;
    GtkWidget *PasswordEntry;
    GtkWidget *DNSEntry;
} domain_window;

typedef struct {
    GtkWidget *Window;

    GtkWidget *StatusBox;
    GtkWidget *HeadLabel;
    
    GtkWidget *OuEntry;

    GtkWidget *CancelButton;
    GtkWidget *SaveButton;
    GtkWidget *AdressEntry;
    GtkWidget *LoginEntry;
    GtkWidget *PasswordEntry;
    GtkWidget *DNSEntry;
    GtkWidget *StatusEntry;
    GtkWidget *CheckButton;
    GtkWidget *KerberosServerEntry;
    GtkWidget *ClientCombo;
    GtkWidget *AdditionalParametersEntry;
    GtkWidget *AdditionalParametersDefaultSwitch;
    GtkWidget *EditButton;
    guint timer_id;
} connection_window;

typedef struct {
    GtkWidget *Window;
    GtkWidget *StatusBox;

    GtkWidget *HeadLabel;

    GtkWidget *ExecuteTerminal;
    GtkWidget *TerminalScroll;
} domain_info_window;

typedef struct {
    GtkWidget *Window;
    GtkWidget *StatusBox;
    GtkWidget *TitleLabel;
    GtkWidget *OptionsTree;
    GtkWidget *OptionsEntry;
    GtkWidget *AcceptButton;
    GtkWidget *CancelButton;
    GtkListStore *List;
    GtkCellRenderer *ChooseCell;
} domain_options_window;

struct locales_struct {
    char *locale;
    char *lang;
    char *territory;
    int chosen;
    GtkListStore *list;
};

void on_save_done(main_window *widgets, config_str output, int size);
void on_config_reload(GtkWidget *,main_window *widgets);
void yon_config_local_load(GtkWidget *self, main_window *widgets);
void yon_config_global_load(GtkWidget *self, main_window *widgets);
void yon_config_custom_load(GtkWidget *self, main_window *widgets);

void yon_load_proceed(YON_CONFIG_TYPE type);

void yon_interface_update(main_window *widgets);

main_window *setup_window();
void on_id_changed(GtkEntry *self, main_window *widgets);

void on_check_domain_connected(GtkWidget *self, main_window *widgets);
void yon_interface_update(main_window *widgets);

void on_hostname_changed(GtkEntry *self, main_window *widgets);
void on_language_changed(GtkComboBox *self, main_window *widgets);
void on_console_font_changed(GtkComboBox *self, main_window *widgets);
void on_hostname_changed(GtkEntry *self, main_window *widgets);
void on_locale_window_closed();
void yon_interface_save(main_window *widgets);
void yon_config_global_local_save(GtkWidget *, main_window *widgets);
void yon_config_local_save(GtkWidget *, main_window *widgets);
void yon_config_global_save(GtkWidget *, main_window *widgets);
void yon_config_custom_save(GtkWidget *, main_window *widgets);
void on_domain_address_save(GtkEntry *self);
void yon_gtk_windget_set_sensitive_from_entry_emptiness(GtkEntry *self, GtkWidget *target);
void on_locale_toggle(GtkCellRenderer *, gchar *path,language_window *window);
void on_locale_accept(GtkWidget *self, language_window *window);
void on_language_open(GtkWidget *self, main_window *widgets);
void on_hostname_changed(GtkEntry *self, main_window *widgets);
void on_id_combo_toggled(GtkComboBox *self, main_window *widgets);
void on_id_changed(GtkEntry *self, main_window *widgets);
void on_id_copy(GtkButton *self, main_window *widgets);
void on_console_font_changed(GtkComboBox *self, main_window *widgets);
void on_language_changed(GtkComboBox *self, main_window *widgets);
void on_terminal_done(VteTerminal *terminal, gint status, dictionary *dict);
void on_terminal_command_ended(VteTerminal *terminal, gint status, domain_info_window *window);
domain_info_window *yon_information_window_new();
void on_domain_connect(GtkWidget *self, dictionary *dict);
void on_status_clicked(GtkWidget *self, connection_window *window);
void on_find_domains_clicked(GtkWidget *self, main_window *window);
void on_main_window_domain_status_clicked(GtkWidget *self, GtkEntryIconPosition icon_pos,GdkEvent* event,main_window *widgets);
gboolean on_main_window_domain_status_update(connection_window *window);
    gboolean yon_update_thread(GtkWidget *self, connection_window *window);
connection_window *yon_connection_window_new();
void on_domain_disconnect(GtkWidget *self, dictionary *dict);
domain_window *yon_domain_window_new();
void on_domain_opened(GtkWidget *self, main_window *widgets);
void on_check_domain_connected(GtkWidget *self, main_window *widgets);
main_window *yon_main_window_complete(main_window *widgets);
void yon_language_update(main_window *widgets);
language_window *yon_language_window_new();
void yon_config_init();
void on_locale_toggled(GtkCellRenderer *, gchar *path, main_window *widgets);
void on_language_default_toggled(GtkWidget *, int status, main_window *widgets);
void on_language_remove(GtkWidget *, main_window *widgets);
gboolean yon_locale_window_set_locales(struct locales_struct *data);
void *yon_locales_load_func(language_window *window);
gboolean yon_locale_window_unlock(GtkWidget *spinner);
void yon_domain_client_changed(GtkWidget*,connection_window *window);
void on_domain_options_accept(GtkWidget *,domain_options_window *dialog);
void on_domain_options_cell_toggled(GtkCellRenderer*, gchar *path,domain_options_window *window);
domain_options_window *yon_domain_options_window_new();
void yon_domain_additional_options_open(GtkWidget *, connection_window *window);
void yon_domain_client_changed_switch(GtkWidget*,int ,connection_window *window);
void on_locale_selection_changed(GtkWidget *,main_window *widgets);
gboolean yon_filter(GtkTreeModel* model, GtkTreeIter *iter, language_window *window);
void on_filer_changed(GtkWidget *, language_window *window);