/* watch.c - Execute a program periodically
 *
 * Copyright 2013 Sandeep Sharma <sandeep.jack2756@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *
 * No standard. See http://man7.org/linux/man-pages/man1/watch.1.html
 *
 * TODO: trailing combining characters
USE_WATCH(NEWTOY(watch, "^<1n%<100=2000tebx", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))

config WATCH
  bool "watch"
  default y
  help
    usage: watch [-teb] [-n SEC] PROG ARGS

    Run PROG every -n seconds, showing output. Hit q to quit.

    -n	Loop period in seconds (default 2)
    -t	Don't print header
    -e	Exit on error
    -b	Beep on command error
    -x	Exec command directly (vs "sh -c")
*/

#define FOR_watch
#include "toys.h"

GLOBALS(
  int n;

  pid_t pid, oldpid;
)

// When a child process exits, stop tracking them. Handle errors for -be
static void watch_child(int sig)
{
  int status;
  pid_t pid = wait(&status);

  status = WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+127;
  if (status) {
    // TODO should this be beep()?
    if (FLAG(b)) putchar('\b');
    if (FLAG(e)) {
      printf("Exit status %d\r\n", status);
      tty_reset();
      _exit(status);
    }
  }

  if (pid == TT.oldpid) TT.oldpid = 0;
  else if (pid == TT.pid) TT.pid = 0;
}

// Return early for low-ascii characters with special behavior,
// discard remaining low ascii, escape other unprintable chars normally
static int watch_escape(FILE *out, int cols, int wc)
{
  if (wc==27 || (wc>=7 && wc<=13)) return -1;
  if (wc < 32) return 0;

  return crunch_escape(out, cols, wc);
}

void watch_main(void)
{
  char *cmdv[] = {"/bin/sh", "-c", 0, 0}, *cmd, *ss;
  long long now, then = millitime();
  unsigned width, height, i, cmdlen, len, xx = xx, yy = yy, active = active;
  struct pollfd pfd[2];
  pid_t pid = 0;
  int fds[2], cc;

  // Assemble header line in cmd, cmdlen, and cmdv
  for (i = TT.n%1000, len = i ? 3 : 1; i && !(i%10); i /= 10) len--;
  len = sprintf(toybuf, "Every %u.%0*us:", TT.n/1000, len, i)+1;
  cmdlen = len;
  for (i = 0; toys.optargs[i]; i++) len += strlen(toys.optargs[i])+1;
  ss = stpcpy(cmd = xmalloc(len), toybuf);
  cmdv[2] = cmd+cmdlen;
  for (i = 0; toys.optargs[i]; i++) ss += sprintf(ss, " %s",toys.optargs[i]);
  cmdlen = ss-cmd;

  // Need to poll on process output and stdin
  memset(pfd, 0, sizeof(pfd));
  pfd[0].events = pfd[1].events = POLLIN;

  xsignal_flags(SIGCHLD, watch_child, SA_RESTART|SA_NOCLDSTOP);

  for (;;) {

    // Time for a new period?
    if ((now = millitime())>=then) {

      // Incrementing then instead of adding offset to now avoids drift,
      // loop is in case we got suspend/resumed and need to skip periods
      while ((then += TT.n)<=now);
      start_redraw(&width, &height);

      // redraw the header
      if (!FLAG(t)) {
        time_t t = time(0);
        int pad, ctimelen;

        // Get and measure time string, trimming gratuitous \n
        ctimelen = strlen(ss = ctime(&t));
        if (ss[ctimelen-1]=='\n') ss[--ctimelen] = 0;
 
        // print cmdline, then * or ' ' (showing truncation), then ctime 
        pad = width-++ctimelen;
        if (pad>0) draw_trim(cmd, -pad, pad);
        printf("%c", pad<cmdlen ? '*' : ' ');
        if (width) xputs(ss+(width>ctimelen ? 0 : width-1));
        if (yy>=3) xprintf("\r\n");
        xx = 0;
        yy = 2;
      }

      // If child didn't exit, send TERM signal to current and KILL to previous
      if (TT.oldpid>0) kill(TT.oldpid, SIGKILL);
      if (TT.pid>0) kill(TT.pid, SIGTERM);
      TT.oldpid = pid;
      if (fds[0]>0) close(fds[0]);
      if (fds[1]>0) close(fds[1]);

      // Spawn child process
      fds[0] = fds[1] = -1;
      TT.pid = xpopen_both(FLAG(x) ? toys.optargs : cmdv, fds);
      pfd[1].fd = fds[1];
      active = 1;
    }

    // Fetch data from child process or keyboard, with timeout
    len = 0;
    xpoll(pfd, 1+(active && yy<height), then-now);
    if (pfd[0].revents&POLLIN) {
      memset(toybuf, 0, 16);
      cc = scan_key_getsize(toybuf, 0, &width, &height);
      // TODO: ctrl-Z suspend
      // TODO if (cc == -3) redraw();
      if (cc == 3 || tolower(cc) == 'q') xexit();
    }
    if (pfd[0].revents&POLLHUP) xexit();
    if (active) {
      if (pfd[1].revents&POLLIN) len = read(fds[1], toybuf, sizeof(toybuf)-1);
      if (pfd[1].revents&POLLHUP) active = 0;
    }

    // Measure output, trim to available display area. Escape low ascii so
    // we don't have to try to parse ansi escapes. TODO: parse ansi escapes.
    if (len<1) continue;
    ss = toybuf;
    toybuf[len] = 0;
    while (yy<height) {
      if (xx==width) {
        xx = 0;
        if (++yy>=height) break;
      }
      xx += crunch_str(&ss, width-xx, stdout, 0, watch_escape);
      if (xx==width) {
        xx = 0;
        if (++yy>=height) break;
        continue;
      }

      if (ss-toybuf==len || *ss>27) break;
      cc = *ss++;
      if (cc==27) continue; // TODO

      // Handle BEL BS HT LF VT FF CR
      if (cc>=10 && cc<=12) {
        if (++yy>=height) break;
        if (cc=='\n') putchar('\r'), xx = 0;
      }
      putchar(cc);
      if (cc=='\b' && xx) xx--;
      else if (cc=='\t') {
        xx = (xx|7)+1;
        if (xx>width-1) xx = width-1;
      }
    }
  }

  if (CFG_TOYBOX_FREE) free(cmd);
}
