/* 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"

#define ALLOCATION_CHUNK (10UL)

static const char * argv0;

static char *
slurp(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;
  char * buffer = malloc(ALLOCATION_CHUNK);
	do {
		if (!((buffer_size + 1) % ALLOCATION_CHUNK)) {
			buffer = realloc(buffer, ((buffer_size + 1) / ALLOCATION_CHUNK + 1) * ALLOCATION_CHUNK);
		}
		buffer[buffer_size] = '\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;
    }
		++buffer_size;
	} while (buffer[buffer_size - 1]);

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

/* TODO: fix the shit going on with syntax/c.h , replace with a function,
 * and ideally how make it hotswappable. */
int
main(int     argc,
     char ** argv) {
  int    arg    = 0;
  int    syn    = 0;
  char * buffer = NULL;

  argv0 = argv[0];

	terminal_hl_init();

  while (++argv,
         --argc)
  {
    if (**argv == '-')
    {
      syn = 1;
      /* fprintf(stderr, "handle '%s'\n", *argv+1); */
      /* lazy as hell, TODO use uthash */
      if (strcmp(*argv+1, "c") == 0)
      {
        #include "syntax/c.h"
      }
      else
      {
        fprintf(stderr, "%s: Unimplemented syntax '%s'\n", argv0, *argv+1);
        return 1;
      }
    }
    else
    {
      if (!syn)
      {
        #include "syntax/c.h"
      }
      free(buffer);
      arg = 1;
      buffer = slurp(*argv);
      render_string(buffer, "cterm");
      if (!buffer)
      {
        perror(argv0);
        return 1;
      }
    }
  }
  if (!arg)
  {
    if (!syn)
    {
      #include "syntax/c.h"
    }
    buffer = get_stdin();
    render_string(buffer, "cterm");
  }

	fflush(stdout);
	//hl_deinit();
	free(buffer);

	//terminal_hl_deinit();

	return 0;
}