/*
 * PSIP - A lightweight GTK GUI for pjsip
 * (C) James Budiono 2011
 * License: GNU GPL Version 3 or later, please see attached gpl-3.0.txt 
 * or http://www.gnu.org/copyleft/gpl.html
 * 
 * All the config-related functions are in this file.
 */

#include <stdlib.h> 
#include <string.h>
#include <stdio.h>

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

#include "cJSON.h"
#include "psip.h"

gchararray config_file;

/* === get location of config file === */
gchararray get_config_file() {
	struct passwd *p;
	p = getpwuid(getuid());
	if (p) {
		config_file = g_strdup_printf("%s" G_DIR_SEPARATOR_S ".%s", p->pw_dir, CONFIG_FILE);
	}
	else config_file = CONFIG_FILE;
	g_print("Config file location: %s\n",config_file);	
	return config_file;
}

/* Parse text to JSON, then render back to text, and print! */
void doit(char *text)
{
	char *out;cJSON *json;
	
	json=cJSON_Parse(text);
	if (!json) {printf("Error before: [%s]\n",cJSON_GetErrorPtr());}
	else
	{
		out=cJSON_Print(json);
		cJSON_Delete(json);
		printf("%s\n",out);
		free(out);
	}
}

/* === default settings === */
void config_load_default() {
	gtk_entry_set_text (psip_state->help_command_field, DEFAULT_HELP_COMMAND);	
}

/* === load config from json file === */
void load_config() {
	get_config_file();
	
	//make sure these objects are not destroyed until we say so		
	g_object_ref(psip_state->buddylist); 
	
	FILE *f=fopen(config_file,"rb");
	if (!f) {
		config_load_default();
		return;
	}
	fseek(f,0,SEEK_END);long len=ftell(f);fseek(f,0,SEEK_SET);
	char *data=malloc(len+1);fread(data,1,len,f);fclose(f);
	
	//doit(data);
	cJSON *root = cJSON_Parse (data);	
		
	//read accounts
	cJSON *account = cJSON_GetObjectItem (root, "account");
	cJSON *settings = cJSON_GetObjectItem (root, "settings");
	gtk_entry_set_text (psip_state->account_sip_url_field, cJSON_GetObjectItem(account, "sip-url")->valuestring);
	gtk_entry_set_text (psip_state->account_registrar_field, cJSON_GetObjectItem(account, "registrar")->valuestring);
	gtk_entry_set_text (psip_state->account_realm_field, cJSON_GetObjectItem(account, "realm")->valuestring);
	gtk_entry_set_text (psip_state->account_user_field, cJSON_GetObjectItem(account, "user")->valuestring);
	gtk_entry_set_text (psip_state->account_password_field, cJSON_GetObjectItem(account, "password")->valuestring);
	gtk_entry_set_text (psip_state->sip_port_field, cJSON_GetObjectItem(settings, "sip-port")->valuestring);	
	gtk_entry_set_text (psip_state->ring_command_field, cJSON_GetObjectItem(settings, "ring-command")->valuestring);
	gtk_range_set_value (GTK_RANGE(psip_state->loglevel_scaler), cJSON_GetObjectItem(settings, "loglevel")->valuedouble);
	gtk_entry_set_text (psip_state->help_command_field, cJSON_GetObjectItem(settings, "help-command")->valuestring);
	
	//read buddies
	clear_default_buddies();	
	cJSON *buddies = cJSON_GetObjectItem (root, "buddies");
	int i, no_of_buddies = cJSON_GetArraySize (buddies);
	for (i=0; i<no_of_buddies; i++) {
		cJSON *buddy = cJSON_GetArrayItem (buddies, i);
		buddylist_add (
			cJSON_GetObjectItem(buddy, "nick")->valuestring,
			cJSON_GetObjectItem(buddy, "address")->valuestring,
			FALSE
		);
	}
	
	cJSON_Delete(root);	
	free(data);	
}


/* === save current config to json file === */
void save_config() {
	cJSON *root, *account, *settings, *buddies;
	
	FILE *f=fopen(config_file,"wb");
	if (!f) return;
	
	//create root objects
	root = cJSON_CreateObject();
	cJSON_AddItemToObject (root, "account", account = cJSON_CreateObject());
	cJSON_AddItemToObject (root, "settings", settings = cJSON_CreateObject());
	cJSON_AddItemToObject (root, "buddies", buddies = cJSON_CreateArray());
	
	//save account
	cJSON_AddStringToObject (account, "sip-url", gtk_entry_get_text(psip_state->account_sip_url_field));
	cJSON_AddStringToObject (account, "registrar", gtk_entry_get_text(psip_state->account_registrar_field));
	cJSON_AddStringToObject (account, "realm", gtk_entry_get_text(psip_state->account_realm_field));
	cJSON_AddStringToObject (account, "user", gtk_entry_get_text(psip_state->account_user_field));
	cJSON_AddStringToObject (account, "password", gtk_entry_get_text(psip_state->account_password_field));
	cJSON_AddStringToObject (settings, "sip-port", gtk_entry_get_text(psip_state->sip_port_field));		
	cJSON_AddStringToObject (settings, "ring-command", gtk_entry_get_text(psip_state->ring_command_field));
	cJSON_AddNumberToObject (settings, "loglevel", gtk_range_get_value(GTK_RANGE(psip_state->loglevel_scaler)));
	cJSON_AddStringToObject (settings, "help-command", gtk_entry_get_text(psip_state->help_command_field));

	//save buddies
	GtkTreeIter i;
	gchararray nick, address;
	cJSON *buddy;

	gboolean ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (psip_state->buddylist), &i);
	while (ok) {
		gtk_tree_model_get (GTK_TREE_MODEL (psip_state->buddylist), &i, BUDDY_NICK, &nick, BUDDY_ADDRESS, &address, GTK_END_OF_LIST); 
		//g_print("%s %s\n", nick, address);
		
		cJSON_AddItemToArray (buddies, buddy = cJSON_CreateObject() );
		cJSON_AddStringToObject (buddy,"nick", nick);
		cJSON_AddStringToObject (buddy,"address", address);
		
		g_free(nick);
		g_free(address);
		ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (psip_state->buddylist), &i);
	}
	g_object_unref (psip_state->buddylist);
	
/*	
	int i;
	cJSON *buddy;
	for (i=0; i<10; i++) {
		cJSON_AddItemToArray (buddies, buddy = cJSON_CreateObject() );
		cJSON_AddStringToObject (buddy,"nick", g_strdup_printf("user%d", i));
		cJSON_AddStringToObject (buddy,"address", g_strdup_printf("sip:user%d@iptel.org", i));
	}
*/	
	//save file
	char *out = cJSON_Print (root);
	//g_print(out);
	fwrite (out,1,strlen(out),f);
	
	free(out);
	cJSON_Delete (root);
	fclose(f);
}

