#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include "libublsettings.h"
#include "libublsettings-gtk3.h"
#include "libublsettingsui-gtk3.h"
#include <locale.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <libintl.h>
#include <getopt.h>
#include <libintl.h>
#include <vte/vte.h>
#include "sys/sysinfo.h"

#ifdef WEBKIT_FOUND
#include <webkit2/webkit2.h>
#endif
#include "ubl-strings.h"
#define config_path yon_char_unite("/home/",yon_ubl_root_user_get(),"/.config/",LocaleName,"/",LocaleName,".conf",NULL)

#define _(String) gettext(String)

#define glade_path "/com/ublinux/ui/ubl-settings-resourcequota.glade"
#define glade_filters_path "/com/ublinux/ui/ubl-settings-resourcequota-filters.glade"
#define glade_quota_path "/com/ublinux/ui/ubl-settings-resourcequota-quota.glade"
#define banner_path "/com/ublinux/images/ubl-settings-resourcequota-banner.png"
#define CssPath "/com/ublinux/css/ubl-settings-resourcequota.css"

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

// #define load_global_command "ubconfig --default --source global get security CGROUP_QUOTA[*]"
// #define load_local_command "ubconfig --default --source system get security CGROUP_QUOTA[*]"
// #define save_global_command "ubconfig --default --target global set security"
// #define save_local_command "ubconfig --default --target system set security"
// #define save_command "ubconfig set security "
// #define remove_command "ubconfig remove security "
// #define remove_global_command "ubconfig --target global --noexecute remove security "
// #define remove_local_command "ubconfig --target system remove security "
#define get_devices_command "clear;findmnt -lo source,target,fstype,label,size -t ext4 |grep -vE \"zram|\\]|\\[|SOURCE\""
#define get_processes_tree_command "clear; systemd-cgls --no-page"
#define get_dispatcher_command "clear; systemd-cgtop -c"
#define get_information_command(target) yon_char_unite("systemctl status ",target,".slice --no-pager",NULL)
#define get_processes_command "systemd-cgls --no-pager |grep -oE \"[-0-9A-Za-z.:]{1,}.service\""
#define get_slices_command "systemd-cgls --no-pager |grep -oE \"[-0-9A-Za-z.:]{1,}.slice\""

#define yon_config_get_custom_command(target) yon_char_unite("ubconfig --source ",target," get security CGROUP_QUOTA[*]",NULL)
#define config_get_local_command "ubconfig --default --source system get security CGROUP_QUOTA[*]"
#define config_get_global_command "ubconfig --default --source global get security CGROUP_QUOTA[*]"
#define config_get_default_command ""

#define config_get_global_only_parameters ""
#define config_get_local_only_parameters ""

#define CGROUP_QUOTA(name) yon_char_unite("CGROUP_QUOTA[",name,"]",NULL)
#define CGROUP_QUOTA_comd(name) yon_char_unite("ubconfig -- source global get security CGROUP_QUOTA[",target,"]",NULL)

#define CGROUP_QUOTA_parameter "CGROUP_QUOTA"
#define CGROUP_QUOTA_command "ubconfig -- source global get security CGROUP_QUOTA"

typedef char *string;

__attribute__((unused)) static \
string version_application;

typedef struct {
    template_config_fields
    int save_config;
    config_str launch_arguments;
    int launch_size;
    GtkListStore *list;
    long avaliable_ram;
    long avaliable_swap;
    long cores;
    
    config_str users;
    int users_size;
    config_str processes;
    int processes_size;
    config_str slices;
    int slices_size;

    char *last_info;
} config;

typedef struct {
    template_window_fields
    // Custom 
    GtkWidget *FiltersButton;
    GtkWidget *InformationButton;
    GtkWidget *RemoveButton;
    GtkWidget *EditButton;
    GtkWidget *AddButton;
    GtkWidget *MainTree;
    GtkWidget *MainNotebook;

    GtkWidget *DispatcherUpdateCheck;
    GtkWidget *DispatcherUpdateSpin;
    GtkWidget *DispatcherUpdateButton;
    GtkWidget *DispatcherTerminal;

    GtkWidget *ShowCoreCheck;
    GtkWidget *ShowAllCheck;
    GtkWidget *ProcessesUpdateButton;
    GtkWidget *ProcessesTerminal;

    GtkWidget *TargetTypeCombo;
    GtkWidget *TargetCombo;
    GtkWidget *InformationUpdateButton;
    GtkWidget *InformationTerminal;
} main_window;


typedef struct {
    GtkWidget *Window;

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

    GtkWidget *CloseButton;
    GtkWidget *AcceptButton;
} documentation_confirmation_window;

typedef struct {
    GtkWidget *Window;
    
    GtkWidget *TitleLabel;
    GtkWidget *StatusBox;
    GtkWidget *BlockUiBox;
    GtkWidget *EditQuotaTargetBox;
    GtkWidget *AddQuotaTargetBox;
    GtkWidget *TargetTypeCombo;
    GtkWidget *TargetCombo;
    GtkWidget *TargetLabel;
    GtkWidget *TypeLabel;
    GtkWidget *SoftRestrictionCheck;
    GtkWidget *SoftRestrictionSpin;
    GtkWidget *SoftRestrictionCombo;
    GtkWidget *HardRestrictionCheck;
    GtkWidget *HardRestrictionSpin;
    GtkWidget *HardRestrictionCombo;
    GtkWidget *PagingLimitCheck;
    GtkWidget *PagingLimitSpin;
    GtkWidget *PagingLimitCombo;
    GtkWidget *CpuLimitCheck;
    GtkWidget *CpuLimitSpin;
    GtkWidget *DeviceLimitCombo;
    GtkWidget *DeviceLimitReadCheck;
    GtkWidget *DeviceLimitReadSpin;
    GtkWidget *DeviceLimitReadCombo;
    GtkWidget *DeviceLimitWriteCheck;
    GtkWidget *DeviceLimitWriteSpin;
    GtkWidget *DeviceLimitWriteCombo;
    GtkWidget *ApplyChangesButton;
    GtkWidget *ManualInputEntry;
    GtkWidget *CancelButton;
    GtkWidget *SaveButton;
    dictionary *devices;
} quota_window;

typedef struct {
    GtkWidget *Window;

    GtkWidget *QuotaTypeCheck;
    GtkWidget *QuotaTargetCheck;
    GtkWidget *SoftRamLimitCheck;
    GtkWidget *HardRamLimitCheck;
    GtkWidget *PagingLimitCheck;
    GtkWidget *CpuLimitCheck;
    GtkWidget *ReadLimitCheck;
    GtkWidget *WriteLimitCheck;
    GtkWidget *CancelButton;
    GtkWidget *AcceptButton;
} filters_window;

typedef struct {
    char *device_name;
    char *read;
    char *write;
} device_limits;

main_window *setup_window();
void on_save_done(main_window *, config_str output, int size);
char *get_size_mod(GtkComboBox *combo);
void yon_main_window_complete(main_window *widgets);
void config_init();
void on_info_target_type_switched(GtkWidget *self, main_window *widgets);
void on_tab_changed(GtkWidget *self, GtkWidget *page, int page_num, main_window *widgets);
void on_processes_update(GtkWidget *self,main_window *widgets);
gboolean on_dispatcher_update(GtkWidget *self,main_window *widgets);
void on_edit_open(GtkWidget *self, main_window *widgets);
void on_quotas_edit(GtkWidget *self, dictionary *windows);
void on_remove(GtkWidget *self, main_window *widgets);
void on_information_update(GtkWidget *self, main_window *widgets);
void on_information(GtkWidget *self, main_window *widgets);
void on_information_chosen_changed(GtkWidget *self, main_window *widgets);
void on_add_open(GtkWidget *self, main_window *widgets);
void on_filters_opened(GtkWidget *self, main_window *widgets);
void on_quota_manual_input_focus (GtkWidget *self,  GdkEventFocus *event, quota_window *window);
void on_quota_manual_input(GtkWidget *self, quota_window *window);
void on_apply_filters(GtkWidget *self, dictionary *dict);
void yon_load_proceed(YON_CONFIG_TYPE type);
void on_config_custom_load(GtkWidget *,main_window *widgets);
void on_config_global_load(GtkWidget *,main_window *widgets);
void on_config_local_load(GtkWidget *,main_window *widgets);
void on_config_custom_save(GtkWidget *, main_window *);
void on_config_global_save(GtkWidget *, main_window *);
void on_config_local_save(GtkWidget *, main_window *);
void on_config_global_local_save(GtkWidget *, main_window *);
void yon_interface_update(main_window *);
int yon_get_size_request_from_letter(char size);
void on_quotas_save(GtkWidget *self, dictionary *windows);
void on_device_current_changed(GtkWidget *self, quota_window *window);
void yon_get_devices(quota_window *window);
void on_target_check_chosen(GtkWidget *self, quota_window *window);
void on_quota_target_type_changed(GtkWidget *self, quota_window *window);
void on_check_maximum_cpu(GtkWidget *self, GtkWidget *pair);
void on_check_maximum(GtkWidget *self, GtkWidget *pair);
void on_limit_manual_input(GtkWidget *self, double *new_value, quota_window *window);
void on_quota_configuration_update(GtkWidget *self, quota_window *window);
void on_device_limits_update(GtkWidget *, quota_window *window);
void yon_widget_set_sensitive(GtkComboBox *toggle, GtkWidget *target);
void on_device_set(GtkWidget *self, quota_window *window);
quota_window *yon_quota_window_new();
void yon_quota_update(quota_window *window);
void on_manual_edit(GtkWidget *, quota_window *window);
gboolean yon_manual_string_finish(GtkWidget *, GdkEvent *,quota_window *window);