/* config2.help.c - config2hep Config.in .config > help.h

   function parse() reads Config.in data into *sym list, then
   we read .config and set sym->try on each enabled symbol.

*/

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <regex.h>
#include <inttypes.h>
#include <termios.h>
#include <poll.h>
#include <sys/socket.h>

struct statvfs {int i;};
#include "lib/portability.h"
#include "lib/lib.h"

// Humor toys.h (lie through our teeth, C's linker doesn't care).
char toys[4096], libbuf[4096], toybuf[4096];
void show_help(FILE *out) {;}
void toy_exec(char *argv[]) {;}
void toy_init(void *which, char *argv[]) {;}

// Parse config files into data structures.

struct symbol {
  struct symbol *next;
  int enabled, help_indent;
  char *name, *depends;
  struct double_list *help;
} *sym;

// remove leading spaces
char *skip_spaces(char *s)
{
  while (isspace(*s)) s++;

  return s;
}

// if line starts with name (as whole word) return pointer after it, else NULL
char *keyword(char *name, char *line)
{
  int len = strlen(name);

  line = skip_spaces(line);
  if (strncmp(name, line, len)) return 0;
  line += len;
  if (*line && !isspace(*line)) return 0;
  line = skip_spaces(line);

  return line;
}

// dlist_pop() freeing wrapper structure for you.
char *dlist_zap(struct double_list **help)
{
  struct double_list *dd = dlist_pop(help);
  char *s = dd->data;

  free(dd);
  
  return s;
}

int zap_blank_lines(struct double_list **help)
{
  int got = 0;

  while (*help) {
    char *s;

    s = skip_spaces((*help)->data);

    if (*s) break;
    got++;
    free(dlist_zap(help));
  }

  return got;
}

// Collect "-a blah" description lines following a blank line (or start).
// Returns array of removed lines with *len entries (0 for none).

// Moves *help to new start of text (in case dash lines were at beginning).
// Sets *from to where dash lines removed from (in case they weren't).
// Discards blank lines before and after dashlines.

// If no prefix, *help NULL. If no postfix, *from == *help
// if no dashlines returned *from == *help.

char **grab_dashlines(struct double_list **help, struct double_list **from,
                      int *len)
{
  struct double_list *dd;
  char *s, **list;
  int count = 0;

  *len = 0;
  zap_blank_lines(help);
  *from = *help;

  // Find start of dash block. Must be at start or after blank line.
  for (;;) {
    s = skip_spaces((*from)->data);
    if (*s == '-' && s[1] != '-' && !count) break;

    if (!*s) count = 0;
    else count++;

    *from = (*from)->next;
    if (*from == *help) return 0;
  }

  // If there was whitespace before this, zap it. This can't take out *help
  // because zap_blank_lines skipped blank lines, and we had to have at least
  // one non-blank line (a dash line) to get this far.
  while (!*skip_spaces((*from)->prev->data)) {
    *from = (*from)->prev;
    free(dlist_zap(from));
  }

  // Count number of dashlines, copy out to array, zap trailing whitespace
  // If *help was at start of dashblock, move it with *from
  count = 0;
  dd = *from;
  if (*help == *from) *help = 0;
  for (;;) {
   if (*skip_spaces(dd->data) != '-') break;
   count++;
   if (*from == (dd = dd->next)) break;
  }

  list = xmalloc(sizeof(char *)*count);
  *len = count;
  while (count) list[--count] = dlist_zap(from);

  return list;
}

// Read Config.in (and includes) to populate global struct symbol *sym list.
void parse(char *filename)
{
  FILE *fp = xfopen(filename, "r");
  struct symbol *new = 0;

  for (;;) {
    char *s, *line = NULL;
    size_t len;

    // Read line, trim whitespace at right edge.
    if (getline(&line, &len, fp) < 1) break;
    s = line+strlen(line);
    while (--s >= line) {
      if (!isspace(*s)) break;
      *s = 0;
    }

    // source or config keyword at left edge?
    if (*line && !isspace(*line)) {
      if ((s = keyword("config", line))) {
        new = xzalloc(sizeof(struct symbol));
        new->next = sym;
        new->name = s;
        sym = new;
      } else if ((s = keyword("source", line))) parse(s);

      continue;
    }
    if (!new) continue;

    if (sym && sym->help_indent) {
      dlist_add(&(new->help), line);
      if (sym->help_indent < 0) {
        sym->help_indent = 0;
        while (isspace(line[sym->help_indent])) sym->help_indent++;
      }
    }
    else if ((s = keyword("depends", line)) && (s = keyword("on", s)))
      new->depends = s;
    else if (keyword("help", line)) sym->help_indent = -1;
  }

  fclose(fp);
}

int charsort(void *a, void *b)
{
  char *aa = a, *bb = b;

  if (*aa < *bb) return -1;
  if (*aa > *bb) return 1;
  return 0;
}

int dashsort(char **a, char **b)
{
  char *aa = *a, *bb = *b;

  if (aa[1] < bb[1]) return -1;
  if (aa[1] > bb[1]) return 1;
  return 0;
}

int dashlinesort(char **a, char **b)
{
  return strcmp(*a, *b);
}

// Three stages: read data, collate entries, output results.

int main(int argc, char *argv[])
{
  FILE *fp;

  if (argc != 3) {
    fprintf(stderr, "usage: config2help Config.in .config\n");
    exit(1);
  }

  // Stage 1: read data. Read Config.in to global 'struct symbol *sym' list,
  // then read .config to set "enabled" member of each enabled symbol.

  // Read Config.in
  parse(argv[1]);

  // read .config
  fp = xfopen(argv[2], "r");
  for (;;) {
    char *line = NULL;
    size_t len;

    if (getline(&line, &len, fp) < 1) break;
    if (!strncmp("CONFIG_", line, 7)) {
      struct symbol *try;
      char *s = line+7;

      for (try=sym; try; try=try->next) {
        len = strlen(try->name);
        if (!strncmp(try->name, s, len) && s[len]=='=' && s[len+1]=='y') {
          try->enabled++;
          break;
        } 
      }
    }
  }

  // Stage 2: process data.

  // Collate help according to usage, depends, and .config

  // Loop through each entry, finding duplicate enabled "usage:" names
  // This is in reverse order, so last entry gets collated with previous
  // entry until we run out of matching pairs.
  for (;;) {
    struct symbol *throw = 0, *catch;
    char *this, *that, *cusage, *tusage, *name = 0;
    int len;

    // find a usage: name and collate all enabled entries with that name
    for (catch = sym; catch; catch = catch->next) {
      if (catch->enabled != 1) continue;
      if (catch->help && (that = keyword("usage:", catch->help->data))) {
        struct double_list *cfrom, *tfrom, *anchor;
        char *try, **cdashlines, **tdashlines, *usage;
        int clen, tlen;

        // Align usage: lines, finding a matching pair so we can suck help
        // text out of throw into catch, copying from this to that
        if (!throw) usage = that;
        else if (strncmp(name, that, len) || !isspace(that[len])) continue;
        catch->enabled++;
        while (!isspace(*that) && *that) that++;
        if (!throw) len = that-usage;
        free(name);
        name = strndup(usage, len);
        that = skip_spaces(that);
        if (!throw) {
          throw = catch;
          this = that;

          continue;
        }

        // Grab option description lines to collate from catch and throw
        tusage = dlist_zap(&throw->help);
        tdashlines = grab_dashlines(&throw->help, &tfrom, &tlen);
        cusage = dlist_zap(&catch->help);
        cdashlines = grab_dashlines(&catch->help, &cfrom, &clen);
        anchor = catch->help;

        // If we've got both, collate and alphebetize
        if (cdashlines && tdashlines) {
          char **new = xmalloc(sizeof(char *)*(clen+tlen));

          memcpy(new, cdashlines, sizeof(char *)*clen);
          memcpy(new+clen, tdashlines, sizeof(char *)*tlen);
          free(cdashlines);
          free(tdashlines);
          qsort(new, clen+tlen, sizeof(char *), (void *)dashlinesort);
          cdashlines = new;

        // If just one, make sure it's in catch.
        } else if (tdashlines) cdashlines = tdashlines;

        // If throw had a prefix, insert it before dashlines, with a
        // blank line if catch had a prefix.
        if (tfrom && tfrom != throw->help) {
          if (throw->help || catch->help) dlist_add(&cfrom, strdup(""));
          else {
            dlist_add(&cfrom, 0);
            anchor = cfrom->prev;
          }
          while (throw->help && throw->help != tfrom)
            dlist_add(&cfrom, dlist_zap(&throw->help));
          if (cfrom && cfrom->prev->data && *skip_spaces(cfrom->prev->data))
            dlist_add(&cfrom, strdup(""));
        }
        if (!anchor) {
          dlist_add(&cfrom, 0);
          anchor = cfrom->prev;
        }

        // Splice sorted lines back in place
        if (cdashlines) {
          tlen += clen;

          for (clen = 0; clen < tlen; clen++) 
            dlist_add(&cfrom, cdashlines[clen]);
        }

        // If there were no dashlines, text would be considered prefix, so
        // the list is definitely no longer empty, so discard placeholder.
        if (!anchor->data) dlist_zap(&anchor);

        // zap whitespace at end of catch help text
        while (!*skip_spaces(anchor->prev->data)) {
          anchor = anchor->prev;
          free(dlist_zap(&anchor));
        }

        // Append trailing lines.
        while (tfrom) dlist_add(&anchor, dlist_zap(&tfrom));

        // Collate first [-abc] option block in usage: lines
        try = 0;
        if (*this == '[' && this[1] == '-' && this[2] != '-' &&
            *that == '[' && that[1] == '-' && that[2] != '-')
        {
          char *from = this+2, *to = that+2;
          int ff = strcspn(from, " ]"), tt = strcspn(to, " ]");

          if (from[ff] == ']' && to[tt] == ']') {
            try = xmprintf("[-%.*s%.*s] ", ff, from, tt, to);
            qsort(try+2, ff+tt, 1, (void *)charsort);
            this = skip_spaces(this+ff+3);
            that = skip_spaces(that+tt+3);
          }
        }

        // The list is definitely no longer empty, so discard placeholder.
        if (!anchor->data) dlist_zap(&anchor);

        // Add new collated line (and whitespace).
        dlist_add(&anchor, xmprintf("%*cusage: %.*s %s%s%s%s",
                  catch->help_indent, ' ', len, name, try ? try : "",
                  this, *this ? " " : "", that));
        free(try);
        dlist_add(&anchor, strdup(""));
        free(cusage);
        free(tusage);
        throw->enabled = 0;
        throw = catch;
        throw->help = anchor->prev->prev;

        throw = catch;
        this = throw->help->data + throw->help_indent + 8 + len;
      }
    }

    // Did we find one?

    if (!throw) break;
  }

  // Stage 3: output results to stdout.

  // Print out help #defines
  while (sym) {
    struct double_list *dd;

    if (sym->help) {
      int i;
      char *s = xstrdup(sym->name);

      for (i = 0; s[i]; i++) s[i] = tolower(s[i]);
      printf("#define HELP_%s \"", s);
      free(s);

      dd = sym->help;
      for (;;) {
        i = sym->help_indent;

        // Trim leading whitespace
        s = dd->data;
        while (isspace(*s) && i) {
          s++;
          i--;
        }
        for (i=0; s[i]; i++) {
          if (s[i] == '"' || s[i] == '\\') putchar('\\');
          putchar(s[i]);
        }
        putchar('\\');
        putchar('n');
        dd = dd->next;
        if (dd == sym->help) break;
      }
      printf("\"\n\n");
    }
    sym = sym->next;
  }

  return 0;
}
