/*
 *========================================================================
 * $Id: wulfstat.h 244 2004-09-30 17:59:32Z rgb $
 *
 * See copyright in copyright.h and the accompanying file COPYING
 *========================================================================
 */

#include "copyright.h"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <pthread.h>
#include <time.h>
#include <math.h>
#include <curses.h>
#include <errno.h>
#include <sys/file.h>
#include <sys/dir.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

/* Sets WULFWARE_VERSION */
#include <wulfware/wulfware_version.h>

/* 
 * This ensures that wulfstat can execute all the commands recognized
 * by xmlsysd, no more and no less.  With a fair bit of work, of course...;-)
 */
#include <wulfware/libwulf_commands.h>

/*
 * This is all structs and enums needed to extract and store the values
 * on a per-host basis for further processing and display.
 */
#include <wulfware/libwulf_values.h>

/*
 * These are structs used to xml-parse wulfhosts
 */
#include <wulfware/libwulf_wulfhosts.h>

/*
 * The primary host structs.  Must be included after wulfhosts.h
 * xml stuff.
 */
#include <wulfware/libwulf_wulfhost.h>

/*
 * Subroutine Prototypes
 */
#include <wulfware/libwulf_prototypes.h>

/* libxml includes */
/*
 * COMPAT using xml-config --cflags to get the include path this will
 * work with both 
 */
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>


/*
 *========================================================================
 * Useful defines
 *========================================================================
 */

#define STDIN	stdin
#define STDOUT	stdout
#define STDERR	stderr
#define OUTFP   stderr
#define YES	1
#define NO	0
#define PI 3.141592653589793238462643
#define K 1024
#define K4 4096
#define K64 65536

/*
 *========================================================================
 * Debug enum -- one per separate component, no particular order
 *========================================================================
 */
 typedef enum {
   D_QUIET,
   D_ALL,
   D_MAIN,
   D_UTIL,
   D_PARSECL,
   D_STARTUP,
   D_WORK,
   D_PARSE,
   D_CONNECT,
   D_INIT_HOST,
   D_CONNECT_HOSTS,
   D_READHOST,
   D_SENDCMD,
   D_SELECT_OPTION,
   D_EXTRACT_VALUES,
   D_INIT_VALUES,
   D_UPDATE_VALUES,
   D_VALUES,
   D_DISPLAY_VALUES,
   D_DISPLAY_DEBUG,
   D_SCREEN,
   D_XMLSYSD,
   D_QUIT,
   N_DEBUG
 } Debug;

 /*
  *========================================================================
  * Subroutine Prototypes
  *========================================================================
  */
 /* from parsecl.c */
 void parsecl(int argc, char **argv);
 void Usage();
 void Usagemap();

 /* from startup.c */
 void startup();

 /* from screen.c */
 void start_screen();
 void start_displaypad();
 void stop_screen();
 void scroll_displaypad(int scroll_lines);

 /* from work.c */
 void work();

 /* from select_option.c */
 void select_option(char c);

 /* quit.c */
 void quit();


 /* from show_status.c */
 void show_status();

 /* from set_display_dctl_state.c */
 void set_display_dctl_state(List *hostlist);
 void dump_dctl_state(Host *hostptr);

 /* from display_values.c */
 void display_basic(List *hostlist);
 void display_net(List *hostlist);
 void display_times(List *hostlist);
 void display_pids(List *hostlist);
 void display_pids_cmdline(List *hostlist);
 void display_memory(List *hostlist);
 void display_load(List *hostlist);
 void display_messages();

 /* Probable cruft */
 void display_values(List *hostlist);
 void display_stat(List *hostlist);
 void display_user(List *hostlist);
 void display_config(List *hostlist);

 /*
  *========================================================================
  * Global Variables and relevant #defines
  *
  * Set the default values and override from the command line in parsecl().
  *========================================================================
  */

/* 
 * verbose is also a debug switch.  One can switch on the debugging
 * of many components of the program with different values.  However
 * one has to read the source to know what turns on what.
 */
 int verbose;
 int udelay;	      /* debug message delay */

/* Default xmlsysd port */
#define XMLSYSD_PORT 7887

/* A few general purpose 64K i/o buffers */
 char inbuf[K64];
 char outbuf[K64];
 char msgbuf[K64];	/* used in recv_xmlDoc() */
/* command buffer, parse buffer, space for hostfile path */
#define MAXFIELDNUMBER 12
 char *command;
 char **fields;
 char hostfile[K];
 char display_msg[K];	/* a global buffer to display errors or messages in */
 char inchar;	/* single character buffer for getch() commands */
 int update_delay;	/* how long to wait between updates */
 int connect_delay;   /* how long to wait between reconnection loops */
 unsigned long long int count;       /* Maximum number of cycles */
 unsigned long long int cycle_cnt;   /* cycle counter */
 Connectlist connectlist; /* Argument struct for threaded connect_to_hosts() */

 /* pthread tid's */
 pthread_t connecttid;

 int numhosts;

 /*
  * ncurses windows.  Scrollable ones need both window (for borders)
  * and pad.  ncurses can't seem to write to the LINES,COLS character
  * without triggering a "7" from xterm for writing past EOL.
  */
 WINDOW *headerwin,*menuwin,*footerwin;
 /* scrollable frame/window combos */
 WINDOW *displaywin,*displaypad;
 WINDOW *debugwin,*debugpad;

/*
 * In order to be able to deal with variable numbers of hosts (add
 * and delete hosts, for example) we MUST make host into a linked list
 * so that we can freely add hosts or delete hosts.  The one thing
 * about this that is "bad" is that we'll have to signficantly change
 * the way we loop over the hostlist -- we have to walk the list
 * until we reach the end instead of advance an index.
 *
 * We'll try doing this in parallel rather than hacking out the one
 * and replacing it all at once.
 */
 List *hostlist;
 List *hosttaglist;
 List *hostrangelist;
 List *iprangelist;

/*
 * We'll also want a couple of linked lists for users and tasks to be
 * monitored.  We will be loading all of this up in read_wulfhosts()
 * for the moment, and working with them in the interactive interface
 * later.
 */
 List *userlist;
 List *tasklist;
/*
 * This determines whether or not to display running root processes,
 * default no.
 */
 int root_flag;

/*
 * The following variables control the state of the display according
 * to what keys are pressed.
 *
 * Most of these are more or less fixed by the display layout, which must
 * have at least 80 columns  The exception is the "display" window, which
 * will always have the largest possible VIEWPORT and which will always be
 * a scrollable virtual (pad) window behind it.
 *
 * A lot of the old members are going to go away.  What we are going to
 * need with the new way of doing things is:
 *    a) type,
 *    b) lines_headerwin, lines_displaywin, lines_displaypad,
 *       lines_menuwin, lines_footerwin, lines_debugwin, lines_debugpad.
 *    c) topline_displaypad, bottomline_displaypad, showline_displaypad,
 *       topline_debugpad, bottomline_debugpad, showline_debugpad
 */
 typedef struct {
   int type;			/* controls the KIND of wulfstat display */
   int current_corner_line;	/* cycles forward or backward in a quasi-ring */
   int lines_headerwin;
   int lines_displaywin;
   int cols_displaywin;
   int lines_displaypad;
   int lines_menuwin;
   int lines_footerwin;
   int lines_debugwin;
   int lines_debugpad;
   int line_displaypad;
   int topline_displaypad;
   int bottomline_displaypad;
   int bottomline_displayed;  /* This counts number of nonblank lines */
   int showline_displaypad;
   int topline_debugpad;
   int bottomline_debugpad;
   int showline_debugpad;
   int lines_per_host;
 } Display;
 /* We should need just one for our single xterm */
 Display display;

 /* 
  * This list of types will eventually allow users to select from 
  * several predefined and simple displays.  Most of the time they
  * will likely choose only load or wulfstat, but if we make the display
  * width depend on what is being shown, a load display might be only
  * 30 characters wide, so that a row of xterm windows, each with a list
  * of perhaps 50 hosts, could conceivably allow hundreds of hosts to be
  * monitored on single X window.
  */
 typedef enum {
   DISPLAY_BASIC,	/* show basic stats */
   DISPLAY_LOAD,	/* show load average only */
   DISPLAY_MEMORY,	/* show memory only */
   DISPLAY_NET,		/* show network loads only */
   DISPLAY_TIMES,	/* show uptime and current time */
   DISPLAY_PIDS,	/* show pids */
   DISPLAY_PIDS_CMDLINE,	/* show pids with cmdline */
   /* The following aren't implemented */
   DISPLAY_STAT,	/* show stat-derived rates (mostly) */
   N_DISPLAYTYPES
 } Displaytypes;
