/*
 *
 * Another test harness for the readline callback interface.
 *
 * Author: Bob Rossi <bob@brasko.net>
 */

#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif

#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <curses.h>

#include <stdlib.h>
#include <unistd.h>

#include <signal.h>

#if 0	/* LINUX */
#include <pty.h>
#else
#include <util.h>
#endif

#ifdef READLINE_LIBRARY
#  include "readline.h"
#else
#  include <readline/readline.h>
#endif

/**
 * Master/Slave PTY used to keep readline off of stdin/stdout.
 */
static int masterfd = -1;
static int slavefd;

void
sigint (s)
     int s;
{
  tty_reset (STDIN_FILENO);
  close (masterfd);
  close (slavefd);
  printf ("\n");
  exit (0);
}

static int 
user_input()
{
  int size;
  const int MAX = 1024;
  char *buf = (char *)malloc(MAX+1);

  size = read (STDIN_FILENO, buf, MAX);
  if (size == -1)
    return -1;

  size = write (masterfd, buf, size);
  if (size == -1)
    return -1;

  return 0;
}

static int 
readline_input()
{
  const int MAX = 1024;
  char *buf = (char *)malloc(MAX+1);
  int size;

  size = read (masterfd, buf, MAX);
  if (size == -1)
    {
      free( buf );
      buf = NULL;
      return -1;
    }

  buf[size] = 0;

  /* Display output from readline */
  if ( size > 0 )
    fprintf(stderr, "%s", buf);

  free( buf );
  buf = NULL;
  return 0;
}

static void 
rlctx_send_user_command(char *line)
{
  /* This happens when rl_callback_read_char gets EOF */
  if ( line == NULL )
    return;
    
  if (strcmp (line, "exit") == 0) {
  	tty_reset (STDIN_FILENO);
  	close (masterfd);
  	close (slavefd);
  	printf ("\n");
	exit (0);
  }
  
  /* Don't add the enter command */
  if ( line && *line != '\0' )
    add_history(line);
}

static void 
custom_deprep_term_function ()
{
}

static int 
init_readline (int inputfd, int outputfd) 
{
  FILE *inputFILE, *outputFILE;

  inputFILE = fdopen (inputfd, "r");
  if (!inputFILE)
    return -1;

  outputFILE = fdopen (outputfd, "w");
  if (!outputFILE)
    return -1;

  rl_instream = inputFILE;
  rl_outstream = outputFILE;

  /* Tell readline what the prompt is if it needs to put it back */
  rl_callback_handler_install("(rltest):  ", rlctx_send_user_command);

  /* Set the terminal type to dumb so the output of readline can be
   * understood by tgdb */
  if ( rl_reset_terminal("dumb") == -1 )
    return -1;

  /* For some reason, readline can not deprep the terminal.
   * However, it doesn't matter because no other application is working on
   * the terminal besides readline */
  rl_deprep_term_function = custom_deprep_term_function;

  using_history();
  read_history(".history"); 

  return 0;
}

static int 
main_loop(void)
{
  fd_set rset;
  int max;
    
  max = (masterfd > STDIN_FILENO) ? masterfd : STDIN_FILENO;
  max = (max > slavefd) ? max : slavefd;

  for (;;)
    {
      /* Reset the fd_set, and watch for input from GDB or stdin */
      FD_ZERO(&rset);
        
      FD_SET(STDIN_FILENO, &rset);
      FD_SET(slavefd, &rset);
      FD_SET(masterfd, &rset);

      /* Wait for input */
      if (select(max + 1, &rset, NULL, NULL, NULL) == -1)
        {
          if (errno == EINTR)
             continue;
          else
            return -1;
        }

      /* Input received through the pty:  Handle it 
       * Wrote to masterfd, slave fd has that input, alert readline to read it. 
       */
      if (FD_ISSET(slavefd, &rset))
        rl_callback_read_char();

      /* Input received through the pty.
       * Readline read from slavefd, and it wrote to the masterfd. 
       */
      if (FD_ISSET(masterfd, &rset))
        if ( readline_input() == -1 )
          return -1;

      /* Input received:  Handle it, write to masterfd (input to readline) */
      if (FD_ISSET(STDIN_FILENO, &rset))
        if ( user_input() == -1 )
          return -1;
  }

  return 0;
}

/* The terminal attributes before calling tty_cbreak */
static struct termios save_termios;
static struct winsize size;
static enum { RESET, TCBREAK } ttystate = RESET;

/* tty_cbreak: Sets terminal to cbreak mode. Also known as noncanonical mode.
 *    1. Signal handling is still turned on, so the user can still type those.
 *    2. echo is off
 *    3. Read in one char at a time.
 *
 * fd    - The file descriptor of the terminal
 * 
 * Returns: 0 on sucess, -1 on error
 */
int tty_cbreak(int fd){
   struct termios buf;
    int ttysavefd = -1;
   
   if(tcgetattr(fd, &save_termios) < 0)
      return -1;
      
   buf = save_termios;
   buf.c_lflag &= ~(ECHO | ICANON);
   buf.c_iflag &= ~(ICRNL | INLCR);
   buf.c_cc[VMIN] = 1;
   buf.c_cc[VTIME] = 0;

#if defined (VLNEXT) && defined (_POSIX_VDISABLE)
   buf.c_cc[VLNEXT] = _POSIX_VDISABLE;
#endif

#if defined (VDSUSP) && defined (_POSIX_VDISABLE)
   buf.c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif

  /* enable flow control; only stty start char can restart output */
#if 0
  buf.c_iflag |= (IXON|IXOFF);
#ifdef IXANY
  buf.c_iflag &= ~IXANY;
#endif
#endif

  /* disable flow control; let ^S and ^Q through to pty */
  buf.c_iflag &= ~(IXON|IXOFF);
#ifdef IXANY
  buf.c_iflag &= ~IXANY;
#endif

  if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)
      return -1;

   ttystate = TCBREAK;
   ttysavefd = fd;

   /* set size */
   if(ioctl(fd, TIOCGWINSZ, (char *)&size) < 0)
      return -1;

#ifdef DEBUG
   err_msg("%d rows and %d cols\n", size.ws_row, size.ws_col);   
#endif
   
   return (0);   
}

int 
tty_off_xon_xoff (int fd)
{
  struct termios buf;
  int ttysavefd = -1;

  if(tcgetattr(fd, &buf) < 0)
    return -1;
     
  buf.c_iflag &= ~(IXON|IXOFF);

  if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)
    return -1;

  return 0;   
}

/* tty_reset: Sets the terminal attributes back to their previous state.
 * PRE: tty_cbreak must have already been called.
 * 
 * fd    - The file descrioptor of the terminal to reset.
 * 
 * Returns: 0 on success, -1 on error
 */
int tty_reset(int fd)
{
   if(ttystate != TCBREAK)
      return (0);

   if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
      return (-1);
      
   ttystate = RESET;
   
   return 0;   
}

int 
main()
{
  int val;
  val = openpty (&masterfd, &slavefd, NULL, NULL, NULL);
  if (val == -1)
    return -1;

  val = tty_off_xon_xoff (masterfd);
  if (val == -1)
    return -1;

  val = init_readline (slavefd, slavefd);
  if (val == -1)
    return -1;

  val = tty_cbreak (STDIN_FILENO);
  if (val == -1)
    return -1;

  signal (SIGINT, sigint);

  val = main_loop ();

  tty_reset (STDIN_FILENO);

  if (val == -1)
    return -1;

  return 0;
}
