/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2022  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 "language2.h"
#include "main.h"
#include "masterdb.h"
#include "tsdl.h"

struct masterdb *masterdb;

struct masterdb *init_masterdb(void){
    struct masterdb *masterdb;

	progress(VTEXT(T_INIT_MASTERDB));		

    masterdb = g_new0(struct masterdb, 1);
    masterdb->masters = z_hash_table_new(g_str_hash, g_str_equal);

    /*z_hash_table_insert(masterdb->masters, g_strdup("OK1ZIA"), "VALUE");
    dbg("OK1ZIA=%s\n", z_hash_table_lookup(masterdb->masters, "OK1ZIA"));
        exit(123);*/
    return masterdb;
}

static gboolean free_masters_item(gpointer key, gpointer value, gpointer user_data){
    
    g_free(key);
    return TRUE;    
}

void free_masterdb(struct masterdb *masterdb){
	progress(VTEXT(T_FREE_MASTERDB));		

    z_hash_table_foreach_remove(masterdb->masters, free_masters_item, NULL);
    z_hash_table_destroy(masterdb->masters);
    g_free(masterdb);
}

gint get_masterdb_size(struct masterdb *masterdb){
    return z_hash_table_size(masterdb->masters);
}

void add_masterdb(struct masterdb *masterdb, gchar *call){
    gchar *masterdbi;
    
    //dbg("add '%s'\n", call);
    masterdbi = z_hash_table_lookup(masterdb->masters, call);
    
    if (!masterdbi){
        z_hash_table_insert(masterdb->masters, g_strdup(call), (gpointer)0x42);
    }
}

gchar *masterdb_search(struct masterdb *masterdb, char *pattern, int maxreslen){
    int reslen;
    GString *gs;
    char *ret;
    GPtrArray *result;
    ZHashNode *node;
    int i;

    result=g_ptr_array_new();
    reslen = 0;
    
    for (i = 0; i < masterdb->masters->size; i++){
        for (node = masterdb->masters->nodes[i]; node; node = node->next){
            gchar *call = (gchar *)node->key;
//            dbg("call=%s pattern=%s\n", call, pattern);
            if (!z_strstr(call, pattern)) continue;

            g_ptr_array_add(result, call);  // foreign key !!!
            if (reslen > 0) reslen++;
            reslen += strlen(call);
            if (reslen >= maxreslen) goto x;
        }
    }
x:;    
    z_ptr_array_qsort((ZPtrArray *)result, z_compare_string); // FIXME GPtr vs. ZPtr ?

    gs = g_string_sized_new(maxreslen+20);
    for (i=0; i<result->len; i++){
        if (gs->len > 0) g_string_append_c(gs, ' ');
        g_string_append(gs, g_ptr_array_index(result, i));
    }
    ret = g_strdup(gs->str);

    g_ptr_array_free(result, TRUE);
    g_string_free(gs, 1);
    return ret;
}

#define MASTERDB_DELIM " \t\r\n"

void load_one_masterdb(struct masterdb *masterdb, gchar *s){
    gchar *call;
    char *token_ptr;
    
    call = strtok_r(s, MASTERDB_DELIM, &token_ptr);
    if (!call) return;

    if (strlen(call)==0) return;
    
    add_masterdb(masterdb, call);
}


int load_masterdb_from_mem(struct masterdb *masterdb, const char *file, const long int len){
    GString *gs; 
	long int pos;
    
    gs = g_string_sized_new(100);
    
    pos=0;
    while(1){
        if (!zfile_mgets(gs, file, &pos, len, 1)) break;
        load_one_masterdb(masterdb, gs->str);
    }
    g_string_free(gs, 1);
    return 0;
}


int load_masterdb_from_file(struct masterdb *masterdb, gchar *filename){
    FILE *f;
	long int len;
	gchar *file;
	int ret;
	size_t r;
    
    f = fopen(filename, "rt");
    if (!f) {
/*        dbg("Can't open '%s'\n",filename);*/
        return -1;
    }
	if (fseek(f, 0L, SEEK_END)<0){
		fclose(f);
		return -1;
	}
	len=ftell(f);
	if (len<=0 || len>0x10000000) {    /* g_new can allocate only gsize=unsigned int */
		fclose(f);
		return -1;
	}
	
	if (fseek(f, 0L, SEEK_SET)<0){
		fclose(f);
		return -1;
	}
	
	file=g_new(gchar, len);
	r=fread(file, 1, len, f);
    fclose(f);
	if (r!=len) return -1;
	ret=load_masterdb_from_mem(masterdb, file, len);
	g_free(file);
	return ret;
}

void read_masterdb_files(struct masterdb *masterdb){
    gchar *s;
    int ret;
    
	progress(VTEXT(T_LOAD_MASTERDB));		

    s = g_strconcat(tucnak_dir, "/tucnakmasters", NULL); 
    ret = load_masterdb_from_file(masterdb, s);
    g_free(s);
    if (ret < 0){
        load_masterdb_from_mem(masterdb, txt_master, sizeof(txt_master));
        load_masterdb_from_mem(masterdb, txt_master1, sizeof(txt_master1));
        load_masterdb_from_mem(masterdb, txt_master2, sizeof(txt_master2));
        load_masterdb_from_mem(masterdb, txt_master3, sizeof(txt_master3));
        load_masterdb_from_mem(masterdb, txt_master4, sizeof(txt_master4));
        load_masterdb_from_mem(masterdb, txt_master5, sizeof(txt_master5));
        load_masterdb_from_mem(masterdb, txt_master6, sizeof(txt_master6));
    }
}





