#define _XOPEN_SOURCE 500  /* strdup */

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

#include <termios.h>

static char *getvalue(int *argip, int argc, char *argv[])
{
  if(*argip >= argc) {
    fprintf(stderr, "Expected an option value\n");
    exit(1);
  }

  return argv[(*argip)++];
}

static int getchoice(int *argip, int argc, char *argv[], const char *options[])
{
  const char *arg = getvalue(argip, argc, argv);

  int value = -1;
  while(options[++value])
    if(streq(arg, options[value]))
      return value;

  fprintf(stderr, "Unrecognised option value %s\n", arg);
  exit(1);
}

typedef enum {
  OFF,
  ON,
  QUERY,
} BoolQuery;

static BoolQuery getboolq(int *argip, int argc, char *argv[])
{
  const char *choices[] = {"off", "on", "query", NULL};
  return getchoice(argip, argc, argv, choices);
}

static char *helptext[] = {
  "reset",
  "s8c1t [off|on]",
  "keypad [app|num]",
  "screen [off|on|query]",
  "cursor [off|on|query]",
  "curblink [off|on|query]",
  "curshape [block|under|bar|query]",
  "mouse [off|click|clickdrag|motion]",
  "reportfocus [off|on|query]",
  "altscreen [off|on|query]",
  "bracketpaste [off|on|query]",
  "icontitle [STR]",
  "icon [STR]",
  "title [STR]",
  NULL
};

static int seticanon(int icanon, int echo)
{
  struct termios termios;
  int ret;

  tcgetattr(0, &termios);

  ret = (termios.c_lflag & ICANON);

  if(icanon) termios.c_lflag |=  ICANON;
  else       termios.c_lflag &= ~ICANON;

  if(echo) termios.c_lflag |=  ECHO;
  else     termios.c_lflag &= ~ECHO;

  tcsetattr(0, TCSANOW, &termios);

  return ret;
}

static void await_c1(unsigned char c1)
{
  unsigned char c;

  /* await CSI - 8bit or 2byte 7bit form */
  int in_esc = FALSE;
  while((c = getchar())) {
    if(c == c1)
      break;
    if(in_esc && c == (char)(c1 - 0x40))
      break;
    if(!in_esc && c == 0x1b)
      in_esc = TRUE;
    else
      in_esc = FALSE;
  }
}

static char *read_csi()
{
  unsigned char csi[32];
  int i = 0;

  await_c1(0x9B); // CSI

  /* TODO: This really should be a more robust CSI parser
   */
  for(; i < sizeof(csi)-1; i++) {
    int c = csi[i] = getchar();
    if(c >= 0x40 && c <= 0x7e)
      break;
  }
  csi[++i] = 0;

  // TODO: returns longer than 32?

  return strdup((char *)csi);
}

static char *read_dcs()
{
  unsigned char dcs[32];
  int in_esc = FALSE;
  int i;

  await_c1(0x90);

  for(i = 0; i < sizeof(dcs)-1; ) {
    char c = getchar();
    if(c == 0x9c) // ST
      break;
    if(in_esc && c == 0x5c)
      break;
    if(!in_esc && c == 0x1b)
      in_esc = TRUE;
    else {
      dcs[i++] = c;
      in_esc = FALSE;
    }
  }
  dcs[++i] = 0;

  return strdup((char *)dcs);
}

static void usage(int exitcode)
{
  char **p;

  fprintf(stderr, "Control a libvterm-based terminal\n"
      "\n"
      "Options:\n");

  for(p = helptext; *p; p++)
    fprintf(stderr, "  %s\n", *p);

  exit(exitcode);
}

static int query_dec_mode(int mode)
{
  char *s = NULL;

  printf("\x1b[?%d$p", mode);

  do {
    int reply_mode, reply_value;
    char reply_cmd;

    if(s)
      free(s);
    s = read_csi();

    /* expect "?" mode ";" value "$y" */

    /* If the sscanf format string ends in a literal, we can't tell from
     * its return value if it matches. Hence we'll %c the cmd and check it
     * explicitly
     */
    if(sscanf(s, "?%d;%d$%c", &reply_mode, &reply_value, &reply_cmd) < 3)
      continue;
    if(reply_cmd != 'y')
      continue;

    if(reply_mode != mode)
      continue;

    free(s);

    if(reply_value == 1 || reply_value == 3)
      return TRUE;
    if(reply_value == 2 || reply_value == 4)
      return FALSE;

    printf("Unrecognised reply to DECRQM: %d\n", reply_value);
    return FALSE;
  } while(1);
}

static void do_dec_mode(int mode, BoolQuery val, const char *name)
{
  switch(val) {
    case OFF:
    case ON:
      printf("\x1b[?%d%c", mode, val == ON ? 'h' : 'l');
      break;

    case QUERY:
      if(query_dec_mode(mode))
        printf("%s on\n", name);
      else
        printf("%s off\n", name);
      break;
  }
}

static int query_rqss_numeric(char *cmd)
{
  char *s = NULL;

  printf("\x1bP$q%s\x1b\\", cmd);

  do {
    int num;

    if(s)
      free(s);
    s = read_dcs();

    if(!s)
      return -1;
    if(strlen(s) < strlen(cmd))
      return -1;
    if(strcmp(s + strlen(s) - strlen(cmd), cmd) != 0) {
      printf("No match\n");
      continue;
    }

    if(s[0] != '1' || s[1] != '$' || s[2] != 'r')
      return -1;

    if(sscanf(s + 3, "%d", &num) != 1)
      return -1;

    return num;
  } while(1);
}

int wasicanon;

void restoreicanon(void)
{
  seticanon(wasicanon, TRUE);
}

int main(int argc, char *argv[])
{
  int argi = 1;

  if(argc == 1)
    usage(0);

  wasicanon = seticanon(FALSE, FALSE);
  atexit(restoreicanon);

  while(argi < argc) {
    const char *arg = argv[argi++];

    if(streq(arg, "reset")) {
      printf("\x1b" "c");
    }
    else if(streq(arg, "s8c1t")) {
      const char *choices[] = {"off", "on", NULL};
      switch(getchoice(&argi, argc, argv, choices)) {
      case 0:
        printf("\x1b F"); break;
      case 1:
        printf("\x1b G"); break;
      }
    }
    else if(streq(arg, "keypad")) {
      const char *choices[] = {"app", "num", NULL};
      switch(getchoice(&argi, argc, argv, choices)) {
      case 0:
        printf("\x1b="); break;
      case 1:
        printf("\x1b>"); break;
      }
    }
    else if(streq(arg, "screen")) {
      do_dec_mode(5, getboolq(&argi, argc, argv), "screen");
    }
    else if(streq(arg, "cursor")) {
      do_dec_mode(25, getboolq(&argi, argc, argv), "cursor");
    }
    else if(streq(arg, "curblink")) {
      do_dec_mode(12, getboolq(&argi, argc, argv), "curblink");
    }
    else if(streq(arg, "curshape")) {
      // TODO: This ought to query the current value of DECSCUSR because it
      //   may need blinking on or off
      const char *choices[] = {"block", "under", "bar", "query", NULL};
      int shape = getchoice(&argi, argc, argv, choices);
      switch(shape) {
        case 3: // query
          shape = query_rqss_numeric(" q");
          switch(shape) {
            case 1: case 2:
              printf("curshape block\n");
              break;
            case 3: case 4:
              printf("curshape under\n");
              break;
            case 5: case 6:
              printf("curshape bar\n");
              break;
          }
          break;

        case 0:
        case 1:
        case 2:
          printf("\x1b[%d q", 1 + (shape * 2));
          break;
      }
    }
    else if(streq(arg, "mouse")) {
      const char *choices[] = {"off", "click", "clickdrag", "motion", NULL};
      switch(getchoice(&argi, argc, argv, choices)) {
      case 0:
        printf("\x1b[?1000l"); break;
      case 1:
        printf("\x1b[?1000h"); break;
      case 2:
        printf("\x1b[?1002h"); break;
      case 3:
        printf("\x1b[?1003h"); break;
      }
    }
    else if(streq(arg, "reportfocus")) {
      do_dec_mode(1004, getboolq(&argi, argc, argv), "reportfocus");
    }
    else if(streq(arg, "altscreen")) {
      do_dec_mode(1049, getboolq(&argi, argc, argv), "altscreen");
    }
    else if(streq(arg, "bracketpaste")) {
      do_dec_mode(2004, getboolq(&argi, argc, argv), "bracketpaste");
    }
    else if(streq(arg, "icontitle")) {
      printf("\x1b]0;%s\a", getvalue(&argi, argc, argv));
    }
    else if(streq(arg, "icon")) {
      printf("\x1b]1;%s\a", getvalue(&argi, argc, argv));
    }
    else if(streq(arg, "title")) {
      printf("\x1b]2;%s\a", getvalue(&argi, argc, argv));
    }
    else {
      fprintf(stderr, "Unrecognised command %s\n", arg);
      exit(1);
    }
  }
  return 0;
}
