/*
 * Kangaroo Punch MultiPlayer Game Server Mark II
 * Copyright (C) 2020-2021  Scott Duensing
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */


#include "db.h"
#include "array.h"

#include "runtime.h"


RuntimeDataT __runtimeData;


void runtimeDataLoad(void) {
	uint16_t    count   = 0;
	char     ***records = NULL;
	char      **fields  = NULL;

	dbQueryMultiple(&records, "SELECT name, data FROM data", NULL);
	if (records) {
		for (count = 0; count < arrlen(records); count++) {
			fields = records[count];
			if (fields) {
				shput(__runtimeData.strings, fields[0], strdup(fields[1]));
			}
		}
	}

	dbResultRelease(&records);

	/*
	logWrite("\n\n");
	for (int r = 0; r < shlen(__runtimeData.strings); r++) {
		logWrite("%s = %s\n", __runtimeData.strings[r].key, __runtimeData.strings[r].value);
	}
	logWrite("\n\n");
	*/
}


void runtimeDataUpdate(void) {
	FILE     *f;
	uint8_t   c;
	char      name[33];
	char      data[1025];
	uint8_t   which       = 0;   // 0 = Reading name, 1 = Reading data.
	uint16_t  x           = 0;

	f = cacheFOpen("generated:client.dat", "rb");
	if (f) {
		while (1) {
			// Get next byte.
			c = fgetc(f);
			// End of file?
			if (feof(f)) break;
			// End of string?
			if (c == 0) {
				if (which == 0) {
					// Got the name, move on to data.
					which++;
					name[x] = 0;
					x = 0;
				} else {
					// Got data.  Write both to database and start over.
					which = 0;
					data[x] = 0;
					x = 0;
					dbExecute(
						"REPLACE INTO data (name, data) VALUES (?, ?)",
						"vv",
						name, data
					);
				}
				continue;
			}
			// Got byte.
			if (which == 0) {
				name[x++] = c;
			} else {
				data[x++] = c;
			}
		}
		cacheFClose(f);
	}

	runtimeDataLoad();
}


void runtimeShutdown(void) {
	// Free string table.
	while (shlen(__runtimeData.strings) > 0) {
		DEL(__runtimeData.strings[0].value);
		shdel(__runtimeData.strings, __runtimeData.strings[0].key);
	}
	shfree(__runtimeData.strings);
}


void runtimeStartup(void) {

	__runtimeData.strings         = NULL;
	__runtimeData.protocolVersion = 0;

	sh_new_strdup(__runtimeData.strings);

	// Do we need to create the client runtime config database?
	dbExecute(
		"CREATE TABLE IF NOT EXISTS data ("
		"name  VARCHAR(32) PRIMARY KEY, "
		"data  VARCHAR(1024) "
		")",
	NULL);
}
