// Require getopt(3)
#define _XOPEN_SOURCE

#include <stdio.h>
#include <string.h>
#define streq(a,b) (strcmp(a,b)==0)

#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "vterm.h"

static const char *special_begin = "{";
static const char *special_end   = "}";

static int parser_text(const char bytes[], size_t len, void *user)
{
  unsigned char *b = (unsigned char *)bytes;

  int i;
  for(i = 0; i < len; ) {
    if(b[i] < 0x20)        // C0
      break;
    else if(b[i] < 0x80)   // ASCII
      i++;
    else if(b[i] < 0xa0)   // C1
      break;
    else if(b[i] < 0xc0)   // UTF-8 continuation
      break;
    else if(b[i] < 0xe0) { // UTF-8 2-byte
      // 2-byte UTF-8
      if(len < i+2) break;
      i += 2;
    }
    else if(b[i] < 0xf0) { // UTF-8 3-byte
      if(len < i+3) break;
      i += 3;
    }
    else if(b[i] < 0xf8) { // UTF-8 4-byte
      if(len < i+4) break;
      i += 4;
    }
    else                   // otherwise invalid
      break;
  }

  printf("%.*s", i, b);
  return i;
}

// 0     1      2      3       4     5      6      7      8      9      A      B      C      D      E      F
static const char *name_c0[] = {
  "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS",  "HT",  "LF",  "VT",  "FF",  "CR",  "LS0", "LS1",
  "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US",
};
static const char *name_c1[] = {
  NULL,  NULL,  "BPH", "NBH", NULL,  "NEL", "SSA", "ESA", "HTS", "HTJ", "VTS", "PLD", "PLU", "RI",  "SS2", "SS3",
  "DCS", "PU1", "PU2", "STS", "CCH", "MW",  "SPA", "EPA", "SOS", NULL,  "SCI", "CSI", "ST",  "OSC", "PM",  "APC",
};

static int parser_control(unsigned char control, void *user)
{
  if(control < 0x20)
    printf("%s%s%s", special_begin, name_c0[control], special_end);
  else if(control >= 0x80 && control < 0xa0 && name_c1[control - 0x80])
    printf("%s%s%s", special_begin, name_c1[control - 0x80], special_end);
  else
    printf("%sCONTROL 0x%02x%s", special_begin, control, special_end);

  if(control == 0x0a)
    printf("\n");
  return 1;
}

static int parser_escape(const char bytes[], size_t len, void *user)
{
  if(bytes[0] >= 0x20 && bytes[0] < 0x30) {
    if(len < 2)
      return -1;
    len = 2;
  }
  else {
    len = 1;
  }

  printf("%sESC %.*s%s", special_begin, (int)len, bytes, special_end);

  return len;
}

// 0     1      2      3       4     5      6      7      8      9      A      B      C      D      E      F
static const char *name_csi_plain[] = {
  "ICH", "CUU", "CUD", "CUF", "CUB", "CNL", "CPL", "CHA", "CUP", "CHT", "ED",  "EL",  "IL",  "DL",  "EF",  "EA",
  "DCH", "SSE", "CPR", "SU",  "SD",  "NP",  "PP",  "CTC", "ECH", "CVT", "CBT", "SRS", "PTX", "SDS", "SIMD",NULL,
  "HPA", "HPR", "REP", "DA",  "VPA", "VPR", "HVP", "TBC", "SM",  "MC",  "HPB", "VPB", "RM",  "SGR", "DSR", "DAQ",
};

//0           4           8           B
static const int newline_csi_plain[] = {
  0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
};

static int parser_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user)
{
  const char *name = NULL;
  if(!leader && !intermed && command < 0x70)
    name = name_csi_plain[command - 0x40];
  else if(leader && streq(leader, "?") && !intermed) {
    // DEC
    switch(command) {
      case 'h': name = "DECSM"; break;
      case 'l': name = "DECRM"; break;
    }
    if(name)
      leader = NULL;
  }

  if(!leader && !intermed && command < 0x70 && newline_csi_plain[command - 0x40])
    printf("\n");

  if(name)
    printf("%s%s", special_begin, name);
  else
    printf("%sCSI", special_begin);

  if(leader && leader[0])
    printf(" %s", leader);

  {
    int i;
    for(i = 0; i < argcount; i++) {
      printf(i ? "," : " ");
  }

    if(args[i] == CSI_ARG_MISSING)
      printf("*");
    else {
      while(CSI_ARG_HAS_MORE(args[i]))
        printf("%ld+", CSI_ARG(args[i++]));
      printf("%ld", CSI_ARG(args[i]));
    }
  }

  if(intermed && intermed[0])
    printf(" %s", intermed);

  if(name)
    printf("%s", special_end);
  else
    printf(" %c%s", command, special_end);

  return 1;
}

static int parser_osc(const char *command, size_t cmdlen, void *user)
{
  printf("%sOSC %.*s%s", special_begin, (int)cmdlen, command, special_end);

  return 1;
}

static int parser_dcs(const char *command, size_t cmdlen, void *user)
{
  printf("%sDCS %.*s%s", special_begin, (int)cmdlen, command, special_end);

  return 1;
}

static VTermParserCallbacks parser_cbs = {
  &parser_text, // text
  &parser_control, // control
  &parser_escape, // escape
  &parser_csi, // csi
  &parser_osc, // osc
  &parser_dcs, // dcs
  NULL // resize
};

int main(int argc, char *argv[])
{
  int use_colour = isatty(1);
  const char *file;
  int fd;
  VTerm *vt;
  int len;
  char buffer[1024];

  int opt;
  while((opt = getopt(argc, argv, "c")) != -1) {
    switch(opt) {
      case 'c': use_colour = 1; break;
    }
  }

  file = argv[optind++];

  if(!file || streq(file, "-"))
    fd = 0; // stdin
  else {
    fd = open(file, O_RDONLY);
    if(fd == -1) {
      fprintf(stderr, "Cannot open %s - %s\n", file, strerror(errno));
      exit(1);
    }
  }

  if(use_colour) {
    special_begin = "\x1b[7m{";
    special_end   = "}\x1b[m";
  }

  // Size matters not for the parser
  vt = vterm_new(25, 80);
  vterm_set_utf8(vt, 1);
  vterm_parser_set_callbacks(vt, &parser_cbs, NULL);

  while((len = read(fd, buffer, sizeof(buffer))) > 0) {
    vterm_input_write(vt, buffer, len);
  }

  printf("\n");

  close(fd);
  vterm_free(vt);

  return 0;
}
