/*
    Tucnak - VHF contest log
    Copyright (C) 2012-2015 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/


#include "header.h"

#include "bfu.h"
#include "fifo.h"
#include "main.h"
#include "menu.h"
#include "rc.h"
#include "session.h"
#include "subwin.h"
#include "terminal.h"
#include "txts.h"
#include "update.h"

char *update_url0 = NULL;
char *update_url1 = NULL;
char *update_file0 = NULL;
char *update_file1 = NULL;
int update_i = 0;
int update_n = 0;
char *update_sh_file = NULL;


struct zserial *update_init_process(void){
	struct zserial *zser;

    //dbg("update_init_process\n");

	zser  = zserial_init_process("/bin/sh", update_sh_file);
	return zser;
}


void update_downloaded(struct zhttp *http){
	GString *fname = g_string_new("");
	char *c;
	const char *d;
	//struct zserial *zser;
#ifdef Z_MSC_MINGW
	SHELLEXECUTEINFO shExecInfo;
	int ret;
#endif

    //dbg("update_downloaded\n");

	c = getenv("TMP");
	if (!c) c = getenv("TEMP");
	if (!c)	c = tucnak_dir;
	g_string_append(fname, c);
	g_string_append_c(fname, '/');

	g_free(update_sh_file);
	update_sh_file = g_strdup_printf("%supdate_tucnak.sh", fname->str);

	d = z_filename(http->page);
	if (!d || !*d) {
		log_addf(VTEXT(T_BAD_UPDATE_FILE_NAME));
		g_string_free(fname, TRUE);
		return;
	}
	g_string_append(fname, d);

	if (zhttp_write_data(http, fname->str)){
		log_adds(http->errorstr);
		g_string_free(fname, TRUE);
		return;
	}



	zhttp_free(http);
	gses->update = http = NULL;
    dbg("update_i=%d update_n=%d fname='%s'\n", update_i, update_n, fname->str);

	if (update_i == 0 && update_n > 1){
		update_i = 1;
        g_free(update_file0);
        update_file0 = g_strdup(fname->str);

		gses->update = http = zhttp_init();
		zhttp_get(http, zsel, update_url1, update_downloaded, NULL);
		return;
	}
    g_free(update_file1);
    update_file1 = g_strdup(fname->str);

    dbg("update_file0='%s' update_file1='%s'\n", update_file0, update_file1);

#ifdef Z_UNIX
    const char *txt_update;
    if (strcmp(PKG, "eee") == 0)
        txt_update = txt_update_eee;
    else
        txt_update = txt_update_deb;

    GString *sh = g_string_sized_new(strlen(txt_update) + 200);
    int dollar = 0;
    const char *cc;
    for (cc = txt_update; *cc != '\0'; cc++){
        if (dollar){
            switch (*cc){
                case '1':
                    if (update_file0) g_string_append(sh, update_file0);
                    break;
                case '2': // pozor, u EEE se nahrazuje $2
                    if (update_file1) g_string_append(sh, update_file1);
                    break;
                default:
                    g_string_append_c(sh, '$');
                    g_string_append_c(sh, *cc);
                    break;
            }
            dollar = 0;
        }else{
            if (*cc == '$'){
                dollar = 1;
            }else{
                g_string_append_c(sh, *cc);
            }
        }
    }

	FILE *f = fopen(update_sh_file, "wt");
	if (!f){
		log_addf(VTEXT(T_CANT_WRITE_S), update_sh_file);
		g_string_free(fname, TRUE);
		g_string_free(sh, TRUE);
		return;
	}
	fprintf(f, "%s", sh->str);
	fclose(f);
	chmod(update_sh_file, 0700);
	g_string_free(sh, TRUE);

	sw_raise_or_new(SWT_UPD);
#endif

#ifdef Z_MSC_MINGW
	z_wokna(fname->str);
	memset(&shExecInfo, 0, sizeof(shExecInfo));
	shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    shExecInfo.fMask = SEE_MASK_FLAG_NO_UI;
	shExecInfo.lpVerb = "runas";
	shExecInfo.lpFile = fname->str;
	shExecInfo.lpParameters = NULL;
	shExecInfo.lpDirectory = NULL;
	shExecInfo.nShow = SW_SHOWNORMAL;
	shExecInfo.hInstApp = NULL;
	//dbg("ShellExecuteEx('runas', '%s', NULL)\n", fname->str);
	ret = ShellExecuteEx(&shExecInfo);
	if (!ret){
		int err = GetLastError();
		GString *gserr = g_string_new(VTEXT(T_CANT_EXECUTE_INSTALLER));
		z_lasterror_e(gserr, err);
		log_adds(gserr->str);
		g_string_free(gserr, TRUE);
	}else{
		//zselect_bh_new(zsel, destroy_terminal, NULL);
		zselect_terminate(zsel);
	}
#endif

#ifdef Z_ANDROID
    android_update_package(fname->str);
	//zselect_bh_new(zsel, destroy_terminal, NULL);
	zselect_terminate(zsel);
#endif

	g_string_free(fname, TRUE);
}

void update_callback(struct zhttp *http){
	char ver[1000], *c, *n, *newver;
	int tok = 0, ofs;
	void *arg = http->arg;


	if (http->errorstr){
		if (http->arg == NULL){ // from menu
			c = g_strdup_printf("%s\n%s", VTEXT(T_UPDATE_OF_TUCNAK_FAILED), http->errorstr);
			msg_box(getml(c, NULL), VTEXT(T_UPDATE_FAILED), AL_CENTER, c, NULL, 1, VTEXT(T_OK), NULL, B_ENTER|B_ESC);
		}
		zhttp_free(http);
		gses->update = NULL;
		return;
	}

	ofs = http->dataofs;
	zbinbuf_getline(http->response, &ofs, ver, sizeof(ver));

	update_i = 0;
	newver = z_tokenize(ver, &tok);
	if (!newver){
		if (http->arg == NULL) log_adds(VTEXT(T_UPDATE_OF_TUCNAK_FAILED_CANT_PARSE_REPLY));
		goto x;
	}
	if (strcasecmp(newver, "E") == 0){
		char *errorstr = z_tokenize(ver, &tok);
		if (http->arg == NULL) log_addf(VTEXT(T_UPDATE_OF_TUCNAK_FAILED_S), errorstr);
		goto x;
	}

	zhttp_free(http);
	gses->update = http = NULL;
	
	if (arg != NULL){ // from win_func
		if (strcasecmp(newver, "A") != 0) log_addf(VTEXT(T_NEW_VERSION_AVAIL), newver);
		return;
	}else{ // from menu
		if (strcasecmp(newver, "A") == 0) {
			log_adds(VTEXT(T_NO_NEW_VER));
			return;
		}
	}

	n = z_tokenize(ver, &tok);
	if (n == NULL){
		log_addf(TRANSLATE("Bad reply from update server"));
		return;
	}

	update_n = atoi(n);
	if (update_i < update_n) {
		update_url0 = g_strdup(z_tokenize(ver, &tok));
		update_i++;
	}
	if (update_i < update_n) {
		update_url1 = g_strdup(z_tokenize(ver, &tok));
		update_i++;
	}

	
	// from menu, got url

	gses->update = http = zhttp_init();
	update_i = 0;
	zhttp_get(http, zsel, update_url0, update_downloaded, NULL);
x:;
	return;
}

void update_tucnak(void *a, void *b){
	struct zhttp *http;
	unsigned long long t1 = (long long)time(NULL) + rand();
	GString *gs;

	//log_adds("UPDATE DISABLED FIXME");
	//return;

	g_free(update_url0);
	g_free(update_url1);
	update_i = 0;
	update_n = 0;

	gses->update = http = zhttp_init();
	gs = g_string_new("http://tucnak.vaiz.cz/update.php");
	zg_string_eprintfa("u", gs, "?ver=%s", VERSION); 
	zg_string_eprintfa("u", gs, "&platform=%s", Z_PLATFORM);
#ifdef Z_UNIX_ANDROID
	zg_string_eprintfa("u", gs, "&pkg=%s", PKG); 
#else
	zg_string_eprintfa("u", gs, "&pkg=%s", "nsis"); 
#endif
	zg_string_eprintfa("u", gs, "&machine=%s", Z_MACHINE); 
	zg_string_eprintfa("u", gs, "&t=%lld", tl);

	//dbg("----------\nupdate_tucnak url='%s'\n", gs->str);
	zhttp_get(http, zsel, gs->str, update_callback, a);
	g_string_free(gs, TRUE);


	if (a != NULL) return;   // called from init()
	update_info(&t1);
}

void update_abort(void *arg){
	if (!gses->update) return;
	zhttp_free(gses->update);
	gses->update = NULL;
}

void update_info(void *arg1){
	struct refresh *r;
	char *c;
	GString *gs;

	if (!gses || !gses->update) return;

	r = (struct refresh*)g_malloc(sizeof(struct refresh));
    r->win = NULL;
    r->fn = update_info;
    r->data = NULL;
    r->timer = -1;

	gs = g_string_new("");
	zhttp_status(gses->update, gs);
	c = g_strdup(gs->str);
	g_string_free(gs, TRUE);

	msg_box(getml(c, NULL), VTEXT(T_UPDATE2)/*VTEXT(T_NINFO)*/, AL_LEFT, c, r, 1, VTEXT(T_CANCEL), update_abort, B_ENTER | B_ESC);
    r->win = term->windows.next;
    ((struct dialog_data *)r->win->data)->dlg->abort = refresh_abort;
    r->timer = zselect_timer_new(zsel, RESOURCE_INFO_REFRESH, (void (*)(void *))refresh, r);
}
