/*
 * hdhomerun_config.c
 *
 * Copyright © 2006-2008 Silicondust USA Inc. <www.silicondust.com>.
 *
 * This library is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * As a special exception to the GNU Lesser General Public License,
 * you may link, statically or dynamically, an application with a
 * publicly distributed version of the Library to produce an
 * executable file containing portions of the Library, and
 * distribute that executable file under terms of your choice,
 * without any of the additional requirements listed in clause 4 of
 * the GNU Lesser General Public License.
 * 
 * By "a publicly distributed version of the Library", we mean
 * either the unmodified Library as distributed by Silicondust, or a
 * modified version of the Library that is distributed under the
 * conditions defined in the GNU Lesser General Public License.
 */

#include "hdhomerun.h"

/*
 * The console output format should be set to UTF-8, however in XP and Vista this breaks batch file processing.
 * Attempting to restore on exit fails to restore if the program is terminated by the user.
 * Solution - set the output format each printf.
 */
#if defined(__WINDOWS__)
#define printf console_printf
#define vprintf console_vprintf
#endif

static const char *appname;

struct hdhomerun_device_t *hd;

static int help(void)
{
	printf("Usage:\n");
	printf("\t%s discover\n", appname);
	printf("\t%s <id> get help\n", appname);
	printf("\t%s <id> get <item>\n", appname);
	printf("\t%s <id> set <item> <value>\n", appname);
	printf("\t%s <id> scan <tuner> [<filename>]\n", appname);
	printf("\t%s <id> save <tuner> <filename>\n", appname);
	printf("\t%s <id> upgrade <filename>\n", appname);
	return -1;
}

static void extract_appname(const char *argv0)
{
	const char *ptr = strrchr(argv0, '/');
	if (ptr) {
		argv0 = ptr + 1;
	}
	ptr = strrchr(argv0, '\\');
	if (ptr) {
		argv0 = ptr + 1;
	}
	appname = argv0;
}

static bool_t contains(const char *arg, const char *cmpstr)
{
	if (strcmp(arg, cmpstr) == 0) {
		return TRUE;
	}

	if (*arg++ != '-') {
		return FALSE;
	}
	if (*arg++ != '-') {
		return FALSE;
	}
	if (strcmp(arg, cmpstr) == 0) {
		return TRUE;
	}

	return FALSE;
}

static uint32_t parse_ip_addr(const char *str)
{
	unsigned int a[4];
	if (sscanf(str, "%u.%u.%u.%u", &a[0], &a[1], &a[2], &a[3]) != 4) {
		return 0;
	}

	return (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0));
}

static int discover_print(char *target_ip_str)
{
	uint32_t target_ip = 0;
	if (target_ip_str) {
		target_ip = parse_ip_addr(target_ip_str);
		if (target_ip == 0) {
			fprintf(stderr, "invalid ip address: %s\n", target_ip_str);
			return -1;
		}
	}

	struct hdhomerun_discover_device_t result_list[64];
	int count = hdhomerun_discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64);
	if (count < 0) {
		fprintf(stderr, "error sending discover request\n");
		return -1;
	}
	if (count == 0) {
		printf("no devices found\n");
		return 0;
	}

	int index;
	for (index = 0; index < count; index++) {
		struct hdhomerun_discover_device_t *result = &result_list[index];
		printf("hdhomerun device %08X found at %u.%u.%u.%u\n",
			(unsigned int)result->device_id,
			(unsigned int)(result->ip_addr >> 24) & 0x0FF, (unsigned int)(result->ip_addr >> 16) & 0x0FF,
			(unsigned int)(result->ip_addr >> 8) & 0x0FF, (unsigned int)(result->ip_addr >> 0) & 0x0FF
		);
	}

	return count;
}

static int cmd_get(const char *item)
{
	char *ret_value;
	char *ret_error;
	if (hdhomerun_device_get_var(hd, item, &ret_value, &ret_error) < 0) {
		fprintf(stderr, "communication error sending request to hdhomerun device\n");
		return -1;
	}

	if (ret_error) {
		printf("%s\n", ret_error);
		return 0;
	}

	printf("%s\n", ret_value);
	return 1;
}

static int cmd_set_internal(const char *item, const char *value)
{
	char *ret_error;
	if (hdhomerun_device_set_var(hd, item, value, NULL, &ret_error) < 0) {
		fprintf(stderr, "communication error sending request to hdhomerun device\n");
		return -1;
	}

	if (ret_error) {
		printf("%s\n", ret_error);
		return 0;
	}

	return 1;
}

static int cmd_set(const char *item, const char *value)
{
	if (strcmp(value, "-") == 0) {
		char *buffer = NULL;
		size_t pos = 0;

		while (1) {
			buffer = (char *)realloc(buffer, pos + 1024);
			if (!buffer) {
				fprintf(stderr, "out of memory\n");
				return -1;
			}

			size_t size = fread(buffer + pos, 1, 1024, stdin);
			pos += size;

			if (size < 1024) {
				break;
			}
		}

		buffer[pos] = 0;

		int ret = cmd_set_internal(item, buffer);

		free(buffer);
		return ret;
	}

	return cmd_set_internal(item, value);
}

static volatile sig_atomic_t sigabort_flag = FALSE;
static volatile sig_atomic_t siginfo_flag = FALSE;
 
static void sigabort_handler(int arg)
{
	sigabort_flag = TRUE;
}

static void siginfo_handler(int arg)
{
	siginfo_flag = TRUE;
}

static void register_signal_handlers(sig_t sigpipe_handler, sig_t sigint_handler, sig_t siginfo_handler)
{
#if defined(SIGPIPE)
	signal(SIGPIPE, sigpipe_handler);
#endif
#if defined(SIGINT)
	signal(SIGINT, sigint_handler);
#endif
#if defined(SIGINFO)
	signal(SIGINFO, siginfo_handler);
#endif
}

static void cmd_scan_printf(FILE *fp, const char *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);

	if (fp) {
		va_list apc;
		va_copy(apc, ap);

		vfprintf(fp, fmt, apc);
		fflush(fp);

		va_end(apc);
	}

	vprintf(fmt, ap);
	fflush(stdout);

	va_end(ap);
}

static int cmd_scan(const char *tuner_str, const char *filename)
{
	if (hdhomerun_device_set_tuner_from_str(hd, tuner_str) <= 0) {
		fprintf(stderr, "invalid tuner number\n");
		return -1;
	}

	char *ret_error;
	if (hdhomerun_device_tuner_lockkey_request(hd, &ret_error) <= 0) {
		fprintf(stderr, "failed to lock tuner\n");
		if (ret_error) {
			fprintf(stderr, "%s\n", ret_error);
		}
		return -1;
	}

	hdhomerun_device_set_tuner_target(hd, "none");

	char *channelmap;
	if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) {
		fprintf(stderr, "failed to query channelmap from device\n");
		return -1;
	}

	const char *channelmap_scan_group = hdhomerun_channelmap_get_channelmap_scan_group(channelmap);
	if (!channelmap_scan_group) {
		fprintf(stderr, "unknown channelmap '%s'\n", channelmap);
		return -1;
	}

	if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) {
		fprintf(stderr, "failed to initialize channel scan\n");
		return -1;
	}

	FILE *fp = NULL;
	if (filename) {
		fp = fopen(filename, "w");
		if (!fp) {
			fprintf(stderr, "unable to create file: %s\n", filename);
			return -1;
		}
	}

	register_signal_handlers(sigabort_handler, sigabort_handler, siginfo_handler);

	int ret = 0;
	while (!sigabort_flag) {
		struct hdhomerun_channelscan_result_t result;
		ret = hdhomerun_device_channelscan_advance(hd, &result);
		if (ret <= 0) {
			break;
		}

		cmd_scan_printf(fp, "SCANNING: %u (%s)\n",
			(unsigned int)result.frequency, result.channel_str
		);

		ret = hdhomerun_device_channelscan_detect(hd, &result);
		if (ret < 0) {
			break;
		}
		if (ret == 0) {
			continue;
		}

		cmd_scan_printf(fp, "LOCK: %s (ss=%u snq=%u seq=%u)\n",
			result.status.lock_str, result.status.signal_strength,
			result.status.signal_to_noise_quality, result.status.symbol_error_quality
		);

		if (result.transport_stream_id_detected) {
			cmd_scan_printf(fp, "TSID: 0x%04X\n", result.transport_stream_id);
		}

		int i;
		for (i = 0; i < result.program_count; i++) {
			struct hdhomerun_channelscan_program_t *program = &result.programs[i];
			cmd_scan_printf(fp, "PROGRAM %s\n", program->program_str);
		}
	}

	hdhomerun_device_tuner_lockkey_release(hd);

	if (fp) {
		fclose(fp);
	}
	if (ret < 0) {
		fprintf(stderr, "communication error sending request to hdhomerun device\n");
	}
	return ret;
}

static void cmd_save_print_stats(void)
{
	struct hdhomerun_video_stats_t stats;
	hdhomerun_device_get_video_stats(hd, &stats);

	fprintf(stderr, "%u packets received, %u overflow errors, %u network errors, %u transport errors, %u sequence errors\n",
		(unsigned int)stats.packet_count, 
		(unsigned int)stats.overflow_error_count,
		(unsigned int)stats.network_error_count, 
		(unsigned int)stats.transport_error_count, 
		(unsigned int)stats.sequence_error_count
	);
}

static int cmd_save(const char *tuner_str, const char *filename)
{
	if (hdhomerun_device_set_tuner_from_str(hd, tuner_str) <= 0) {
		fprintf(stderr, "invalid tuner number\n");
		return -1;
	}

	FILE *fp;
	if (strcmp(filename, "null") == 0) {
		fp = NULL;
	} else if (strcmp(filename, "-") == 0) {
		fp = stdout;
	} else {
		fp = fopen(filename, "wb");
		if (!fp) {
			fprintf(stderr, "unable to create file %s\n", filename);
			return -1;
		}
	}

	int ret = hdhomerun_device_stream_start(hd);
	if (ret <= 0) {
		fprintf(stderr, "unable to start stream\n");
		if (fp && fp != stdout) {
			fclose(fp);
		}
		return ret;
	}

	register_signal_handlers(sigabort_handler, sigabort_handler, siginfo_handler);

	struct hdhomerun_video_stats_t stats_old, stats_cur;
	hdhomerun_device_get_video_stats(hd, &stats_old);

	uint64_t next_progress = getcurrenttime() + 1000;

	while (!sigabort_flag) {
		uint64_t loop_start_time = getcurrenttime();

		if (siginfo_flag) {
			fprintf(stderr, "\n");
			cmd_save_print_stats();
			siginfo_flag = FALSE;
		}

		size_t actual_size;
		uint8_t *ptr = hdhomerun_device_stream_recv(hd, VIDEO_DATA_BUFFER_SIZE_1S, &actual_size);
		if (!ptr) {
			msleep_approx(64);
			continue;
		}

		if (fp) {
			if (fwrite(ptr, 1, actual_size, fp) != actual_size) {
				fprintf(stderr, "error writing output\n");
				return -1;
			}
		}

		if (loop_start_time >= next_progress) {
			next_progress += 1000;
			if (loop_start_time >= next_progress) {
				next_progress = loop_start_time + 1000;
			}

			/* Windows - indicate activity to suppress auto sleep mode. */
			#if defined(__WINDOWS__)
			SetThreadExecutionState(ES_SYSTEM_REQUIRED);
			#endif

			/* Video stats. */
			hdhomerun_device_get_video_stats(hd, &stats_cur);

			if (stats_cur.overflow_error_count > stats_old.overflow_error_count) {
				fprintf(stderr, "o");
			} else if (stats_cur.network_error_count > stats_old.network_error_count) {
				fprintf(stderr, "n");
			} else if (stats_cur.transport_error_count > stats_old.transport_error_count) {
				fprintf(stderr, "t");
			} else if (stats_cur.sequence_error_count > stats_old.sequence_error_count) {
				fprintf(stderr, "s");
			} else {
				fprintf(stderr, ".");
			}

			stats_old = stats_cur;
			fflush(stderr);
		}

		int32_t delay = 64 - (int32_t)(getcurrenttime() - loop_start_time);
		if (delay <= 0) {
			continue;
		}

		msleep_approx(delay);
	}

	if (fp) {
		fclose(fp);
	}

	hdhomerun_device_stream_stop(hd);

	fprintf(stderr, "\n");
	fprintf(stderr, "-- Video statistics --\n");
	cmd_save_print_stats();

	return 0;
}

static int cmd_upgrade(const char *filename)
{
	FILE *fp = fopen(filename, "rb");
	if (!fp) {
		fprintf(stderr, "unable to open file %s\n", filename);
		return -1;
	}

	printf("uploading firmware...\n");
	if (hdhomerun_device_upgrade(hd, fp) <= 0) {
		fprintf(stderr, "error sending upgrade file to hdhomerun device\n");
		fclose(fp);
		return -1;
	}

	fclose(fp);
	msleep_minimum(2000);

	printf("upgrading firmware...\n");
	msleep_minimum(8000);

	printf("rebooting...\n");
	int count = 0;
	char *version_str;
	while (1) {
		if (hdhomerun_device_get_version(hd, &version_str, NULL) >= 0) {
			break;
		}

		count++;
		if (count > 30) {
			fprintf(stderr, "error finding device after firmware upgrade\n");
			return -1;
		}

		msleep_minimum(1000);
	}

	printf("upgrade complete - now running firmware %s\n", version_str);
	return 0;
}

static int cmd_execute(void)
{
	char *ret_value;
	char *ret_error;
	if (hdhomerun_device_get_var(hd, "/sys/boot", &ret_value, &ret_error) < 0) {
		fprintf(stderr, "communication error sending request to hdhomerun device\n");
		return -1;
	}

	if (ret_error) {
		printf("%s\n", ret_error);
		return 0;
	}

	char *end = ret_value + strlen(ret_value);
	char *pos = ret_value;

	while (1) {
		if (pos >= end) {
			break;
		}

		char *eol_r = strchr(pos, '\r');
		if (!eol_r) {
			eol_r = end;
		}

		char *eol_n = strchr(pos, '\n');
		if (!eol_n) {
			eol_n = end;
		}

		char *eol = eol_r;
		if (eol_n < eol) {
			eol = eol_n;
		}

		char *sep = strchr(pos, ' ');
		if (!sep || sep > eol) {
			pos = eol + 1;
			continue;
		}

		*sep = 0;
		*eol = 0;

		char *item = pos;
		char *value = sep + 1;

		printf("set %s \"%s\"\n", item, value);

		cmd_set_internal(item, value);

		pos = eol + 1;
	}

	return 1;
}

static int main_cmd(int argc, char *argv[])
{
	if (argc < 1) {
		return help();
	}

	char *cmd = *argv++; argc--;

	if (contains(cmd, "key")) {
		if (argc < 2) {
			return help();
		}
		uint32_t lockkey = strtoul(argv[0], NULL, 0);
		hdhomerun_device_tuner_lockkey_use_value(hd, lockkey);

		cmd = argv[1];
		argv+=2; argc-=2;
	}

	if (contains(cmd, "get")) {
		if (argc < 1) {
			return help();
		}
		return cmd_get(argv[0]);
	}

	if (contains(cmd, "set")) {
		if (argc < 2) {
			return help();
		}
		return cmd_set(argv[0], argv[1]);
	}

	if (contains(cmd, "scan")) {
		if (argc < 1) {
			return help();
		}
		if (argc < 2) {
			return cmd_scan(argv[0], NULL);
		} else {
			return cmd_scan(argv[0], argv[1]);
		}
	}

	if (contains(cmd, "save")) {
		if (argc < 2) {
			return help();
		}
		return cmd_save(argv[0], argv[1]);
	}

	if (contains(cmd, "upgrade")) {
		if (argc < 1) {
			return help();
		}
		return cmd_upgrade(argv[0]);
	}

	if (contains(cmd, "execute")) {
		return cmd_execute();
	}

	return help();
}

static int main_internal(int argc, char *argv[])
{
#if defined(__WINDOWS__)
	/* Initialize network socket support. */
	WORD wVersionRequested = MAKEWORD(2, 0);
	WSADATA wsaData;
	WSAStartup(wVersionRequested, &wsaData);
#endif

	extract_appname(argv[0]);
	argv++;
	argc--;

	if (argc == 0) {
		return help();
	}

	char *id_str = *argv++; argc--;
	if (contains(id_str, "help")) {
		return help();
	}
	if (contains(id_str, "discover")) {
		if (argc < 1) {
			return discover_print(NULL);
		} else {
			return discover_print(argv[0]);
		}
	}

	/* Device object. */
	hd = hdhomerun_device_create_from_str(id_str, NULL);
	if (!hd) {
		fprintf(stderr, "invalid device id: %s\n", id_str);
		return -1;
	}

	/* Device ID check. */
	uint32_t device_id_requested = hdhomerun_device_get_device_id_requested(hd);
	if (!hdhomerun_discover_validate_device_id(device_id_requested)) {
		fprintf(stderr, "invalid device id: %08X\n", (unsigned int)device_id_requested);
	}

	/* Connect to device and check model. */
	const char *model = hdhomerun_device_get_model_str(hd);
	if (!model) {
		fprintf(stderr, "unable to connect to device\n");
		hdhomerun_device_destroy(hd);
		return -1;
	}

	/* Command. */
	int ret = main_cmd(argc, argv);

	/* Cleanup. */
	hdhomerun_device_destroy(hd);

	/* Complete. */
	return ret;
}

int main(int argc, char *argv[])
{
	int ret = main_internal(argc, argv);
	if (ret <= 0) {
		return 1;
	}
	return 0;
}
