/* source: xiohelp.c */
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
/* Published under the GNU General Public License V.2, see file COPYING */

/* this file contains the source for the help function */

#include "xiosysincludes.h"
#include "xioopen.h"

#include "xiohelp.h"

#if WITH_HELP

/* keep consistent with xioopts.h:enum e_types ! */
static const char *optiontypenames[] = {
	"CONST",	"BIN",		"BOOL",		"BYTE",
	"INT",		"INT/NULL",	"LONG",		"STRING",	"PTRDIFF",
	"SHORT",	"SIZE_T",	"SOCKADDR",	"UNSIGNED-INT",
	"UNSIGNED-LONG","UNSIGNED-SHORT","MODE_T",	"GID_T",
	"UID_T",	"INT[3]",	"STRUCT-TIMEVAL", "STRUCT-TIMESPEC",
	"DOUBLE",	"STRING-NULL",	"LONG-LONG",	"OFF_T",
	"OFF64_T",	"INT:INT",	"INT:INTP",	"INT:BIN",
	"INT:STRING",	"INT:INT:INT",	"INT:INT:BIN",	"INT:INT:STRING",
	"INT:INT:GENERIC",
	"IP4NAME",	"IP4SOCK",
#if HAVE_STRUCT_LINGER
			"STRUCT-LINGER",
#endif
#if HAVE_STRUCT_IP_MREQN
					"STRUCT-IP_MREQN",
#elif HAVE_STRUCT_IP_MREQ
					"STRUCT-IP_MREQ",
#endif
#if HAVE_STRUCT_IP_MREQ_SOURCE
	"IP-MREQ-SOURCE",
#endif
	"GENERIC",
} ;


/* keep consistent with xioopts.h:#define GROUP_* ! */
static const char *addressgroupnames[] = {
	"FD",		"FIFO",		"CHR",		"BLK",
	"REG",		"SOCKET",	"READLINE",	"undef",
	"NAMED",	"OPEN",		"EXEC",		"FORK",
	"LISTEN",	"SHELL",	"CHILD",	"RETRY",
	"TERMIOS",	"RANGE",	"PTY",		"PARENT",
	"UNIX",		"IP4",		"IP6",		"INTERFACE",
	"UDP",		"TCP",		"SOCKS4",	"OPENSSL",
	"PROCESS",	"APPL",		"HTTP",		"undef",
	"SCTP",		"POSIXMQ"
} ;

/* keep consistent with xioopts.h:enum ephase ! */
static char *optionphasenames[] = {
	"ALL",		"INIT",		"EARLY",
	"PREOPEN",	"OPEN",		"PASTOPEN",
	"PRESOCKET",	"SOCKET",	"PASTSOCKET",
	"PREBIGEN",	"BIGEN",	"PASTBIGEN",
	"FD",
	"PREBIND",	"BIND",		"PASTBIND",
	"PRELISTEN",	"LISTEN",	"PASTLISTEN",
	"PRECONNECT",	"CONNECT",	"PASTCONNECT",
	"PREACCEPT",	"ACCEPT",	"PASTACCEPT",
	"CONNECTED",
	"PREFORK",	"FORK",		"PASTFORK",
	"LATE",		"LATE2",
	"PREEXEC",	"EXEC",		"PASTEXEC",
	"SPECIFIC",
	NULL
} ;


/* print a line about a single option */
static int xiohelp_option(FILE *of, const struct optname *on, const char *name) {
   int chars;
   int i, j;
   groups_t groups;
   bool occurred;

   chars = fprintf(of, "      %s", name);
   i = (16 - chars + 7) / 8;
   for (; i > 0; --i) { fputc('\t', of); }
   fputc('\t', of);

   fputs("groups=", of);
   groups = on->desc->group;
   occurred = false;
   chars = 7;
   for (j = 0; j < 8*sizeof(groups_t); ++j) {
      if (groups & 1) {
	 if (occurred) {
	    fputc(',', of);
	    ++chars;
	 }
	 fputs(addressgroupnames[j], of);
	 chars += strlen(addressgroupnames[j]);
	 occurred = true;
      }
      groups >>= 1;
   }
   i = (24 - chars + 7) / 8;
   for (; i > 0; --i) { fputc('\t', of); }

   chars = fprintf(of, "phase=%s", optionphasenames[on->desc->phase]);
   i = (24 - chars + 7) / 8;
   for (; i > 0; --i) { fputc('\t', of); }

   fprintf(of, "type=%s", optiontypenames[on->desc->type]);
   fputc('\n', of);
   return 0;
}

const char *xiohelp_opttypename(enum e_types typnum)
{
	if (typnum < 0 || typnum >= TYPE_OVERFLOW) {
		Warn2("%s(): invalid type number %d", __func__, typnum);
		return "<invalid>";
	}
	return optiontypenames[typnum];
}

int xioopenhelp(FILE *of,
	       int level	/* 0..only addresses, 1..and options */
	       ) {
   const struct addrname *an;
   const struct optname *on;
   int i, j;
   groups_t groups;
   bool occurred;

   fputs("   bi-address:  /* is an address that may act both as data sync and source */\n", of);
   fputs("      <single-address>\n", of);
   fputs("      <single-address>!!<single-address>\n", of);
   fputs("   single-address:\n", of);
   fputs("      <address-head>[,<opts>]\n", of);
   fputs("   address-head:\n", of);
   an = &addressnames[0];
   i = 0;
   while (addressnames[i].name) {
      if (!strcmp(an->name, an->desc->defname)) {
	 int chars, i;

         /* it is a canonical address name */
	 chars = fprintf(of, "      %s", an->name);
	 if (an->desc->syntax) {
	    fputs(an->desc->syntax, of);
	    chars += strlen(an->desc->syntax);
	 }
	 i = (40 - chars + 7) / 8;
	 for (; i > 0; --i) { fputc('\t', of); }
	 fputs("\tgroups=", of);
	 groups = an->desc->groups;  occurred = false;
	 for (j = 0; j < 32; ++j) {
	    if (groups & 1) {
	       if (occurred) { fputc(',', of); }
	       fprintf(of, "%s", addressgroupnames[j]);
	       occurred = true;
	    }
	    groups >>= 1;
	 }
	 fputc('\n', of);
      } else if (level == 2) {
	 int chars, i;

         chars = fprintf(of, "      %s", an->name);
	 i = (40 - chars + 7) / 8;
	 for (; i > 0; --i) { fputc('\t', of); }

         fprintf(of, "\tis an alias name for %s\n", an->desc->defname);
      }
      ++an; ++i;
   }
   if (level == 2) {
      fputs("         <num> is a short form for fd:<num>\n", of);
      fputs("         <filename> is a short form for gopen:<filename>\n", of);
   }

   if (level <= 0)  return 0;

   fputs("   opts:\n", of);
   fputs("      <opt>{,<opts>}:\n", of);
   fputs("   opt:\n", of);
   on = optionnames;
   while (on->name != NULL) {
      if (on->desc->nickname != NULL
	  && !strcmp(on->name, on->desc->nickname)) {
	 if (level == 2) {
	    int chars, i;

	    chars = fprintf(of, "      %s", on->name);
	    i = (16 - chars + 7) / 8;
	    for (; i > 0; --i) { fputc('\t', of); }

	    fprintf(of, "\tis an alias for %s\n", on->desc->defname);
	 } else {
	    xiohelp_option(of, on, on->name);
	 }
      } else if (on->desc->nickname == NULL &&
		 !strcmp(on->name, on->desc->defname)) {
	 xiohelp_option(of, on, on->name);
      } else if (level == 2) {
	 if (!strcmp(on->name, on->desc->defname)) {
	    xiohelp_option(of, on, on->name);
	 } else {
	    int chars, i;

	    chars = fprintf(of, "      %s", on->name);
	    i = (16 - chars + 7) / 8;
	    for (; i > 0; --i) { fputc('\t', of); }

	    fprintf(of, "\tis an alias for %s\n", on->desc->defname);
	 }
      }
      ++on;
   }
   fflush(of);
   return 0;
}

/* This function may be used by address handling code to log syntax error */
int xiohelp_syntax(
	const char *addr,
	int expectnum,
	int isnum,
	const char *syntax)
{
	Error4("%s: wrong number of parameters (%d instead of %d): usage: %s",
	       addr, isnum, expectnum, syntax);
	return -1;
}

#endif /* WITH_HELP */
