/* main.c
 * Copyright 2023 Anon Anonson, Ognjen 'xolatile' Milan Robovic, Emil Williams
 * SPDX Identifier: GPL-3.0-only / NO WARRANTY / NO GUARANTEE */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#include "terminal.h"
#include "syntax/syntax.h"

#define ALLOCATION_CHUNK (128UL)

static const char * argv0;

static char *
read_entire_file(const char * fn)
{
	FILE * fp = fopen(fn, "r");
	if (fp)
	{
		size_t len;
		char * b;
		fseek(fp, 0, SEEK_END);
		len = ftell(fp);
		rewind(fp);
		b = malloc(len + 1);
		if (b && fread(b, 1, len, fp)) {
			b[len] = '\0';
		}
		fclose(fp);
		return b;
	}
	else
	{ return NULL; }
}

static char *
get_stdin(void)
{
	size_t buffer_size = 0;
	size_t n = 1;
	char * buffer = malloc(ALLOCATION_CHUNK);
	if (!buffer)
	{ return NULL; }
	do {
		if (buffer_size + 1 >= (ALLOCATION_CHUNK * n)) {
			buffer = realloc(buffer, ALLOCATION_CHUNK * ++n + 1);
			if (!buffer)
			{ return NULL; }
			buffer[ALLOCATION_CHUNK * n] = '\0';
		}
		if (read(STDIN_FILENO, &buffer[buffer_size], sizeof (*buffer)) == -1)
		{
			free(buffer);
			fprintf(stderr, "%s: Failed to read from stdin\n", argv0);
			return NULL;
		}
	} while (buffer[buffer_size++]);

	buffer[buffer_size - 1] = '\0';
	return buffer;
}

int
main(int     argc,
     char ** argv) {
	int    arg    = 0;
	int    ret    = 0;
	char * buffer = NULL;
	argv0 = argv[0];
	terminal_hl_init();
	highlight_c(); /* this mustn't break overrides (but definitely does) */
	while (++argv,
				 --argc) {
		if (**argv == '-') {
			/* TODO use uthash */
			if (strcmp(*argv+1, "c") == 0) {
				highlight_c();
			}
			else {
				fprintf(stderr, "%s: Unimplemented syntax '%s'\n", argv0, *argv+1);
				return 1;
			}
		}
		else {
			free(buffer);
			arg = 1;
			buffer = read_entire_file(*argv);
			if (!buffer) {
				fprintf(stderr,"%s: cannot access '%s': ", argv0, *argv);
				perror(NULL);
				ret = 2;
			}
			else
			{ render_string(buffer, "cterm"); }
		}
	}
	if (!arg) {
		buffer = get_stdin();
		render_string(buffer, "cterm");
	}
	fflush(stdout);
	hl_deinit();
	free(buffer);
	return ret;
}