/* 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",
	"POSIXMQ",	"SCTP",		"DCCP",		"UDPLITE"
} ;

/* 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)
{
	Error5("%s: wrong number of parameters (%d instead of %d): usage: %s%s",
	       addr, isnum, expectnum, addr, syntax);
	return -1;
}

#endif /* WITH_HELP */
