/* $Id: warehouse-lists.pc 4052 2011-09-19 14:56:35Z zacheiss $
 *
 * (c) Copyright 2008 by the Massachusetts Institute of Technology.
 */

#include <mit-copyright.h>
#include <moira.h>
#include <moira_site.h>

#include <sys/stat.h>

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "util.h"

EXEC SQL INCLUDE sqlca;

char *whoami = "warehouse-lists.gen";
char *db = "moira/moira";

struct hash *lists;

void output_list(int id, void *list, void *out);

int main(int argc, char **argv)
{
  char filename[MAXPATHLEN], *targetfile, *l;
  FILE *out = stdout;
  int cnt = 0;
  EXEC SQL BEGIN DECLARE SECTION;
  int lid;
  char lname[LIST_NAME_SIZE];
  EXEC SQL END DECLARE SECTION;

  EXEC SQL CONNECT :db;

  if (argc == 2)
    {
      targetfile = argv[1];
      sprintf(filename, "%s~", targetfile);
      if (!(out = fopen(filename, "w")))
        {
          fprintf(stderr, "unable to open %s for output\n", filename);
          exit(MR_OCONFIG);
        }
    }
  else if (argc != 1)
    {
      fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
      exit(MR_ARGS);
    }
  
  lists = create_hash(15000);

  EXEC SQL DECLARE l_cursor CURSOR FOR
    SELECT l.list_id, l.name FROM list l
    WHERE l.active = 1 and l.hidden = 0;
  EXEC SQL OPEN l_cursor;
  while (1)
    {
       EXEC SQL FETCH l_cursor INTO :lid, :lname;
       if (sqlca.sqlcode)
	 break;
       l = strdup(strtrim(lname));
       if (hash_store(lists, lid, l) < 0)
	 {
	   fprintf(stderr, "Out of memory!\n");
	   exit(MR_NO_MEM);
	 }
       cnt++;
    }
  EXEC SQL CLOSE l_cursor;
  fprintf(stderr, "Loaded %d lists\n", cnt);

  hash_step(lists, output_list, out);
  
  if (fclose(out))
    {
      perror("close failed");
      exit(MR_CCONFIG);
    }
  
  if (argc == 2)
    fix_file(targetfile);
  exit(MR_SUCCESS);
}

void output_list(int id, void *list, void *out)
{
  EXEC SQL BEGIN DECLARE SECTION;
  char *l = list;
  int lid = id, count;
  char acl_type[LIST_ACL_TYPE_SIZE], modtime[LIST_MODTIME_SIZE];
  char acl_name[STRINGS_STRING_SIZE], login[USERS_LOGIN_SIZE];
  char principal[STRINGS_STRING_SIZE], description[LIST_DESCRIPTION_SIZE];
  int acl_id, active, maillist, grouplist, nfsgroup, publicflg, hidden;
  EXEC SQL END DECLARE SECTION;
  char *maybecomma = "";

  EXEC SQL SELECT acl_type, acl_id, modtime, active, maillist,
    grouplist, nfsgroup, publicflg, hidden, description INTO :acl_type,
    :acl_id, :modtime, :active, :maillist, :grouplist, :nfsgroup,
    :publicflg, :hidden, :description	    
    FROM list WHERE list_id = :lid;
  
  strtrim(acl_type);
  strtrim(modtime);
  strtrim(description);

  for (count = 0; count < strlen(description); count++)
    {
      if (description[count] == '|')
	description[count] = '-';
    }

  strcpy(acl_name, "NONE");
  if (strcmp(acl_type, "LIST") == 0)
    EXEC SQL SELECT name into :acl_name FROM list WHERE list_id = :acl_id;
  else if (strcmp(acl_type, "USER") == 0)
    EXEC SQL SELECT login into :acl_name FROM users WHERE users_id = :acl_id;
  else if (strcmp(acl_type, "KERBEROS") == 0)
    EXEC SQL SELECT string into :acl_name FROM strings WHERE string_id = :acl_id;
  strtrim(acl_name);

  fprintf(out, "%s|%s|%s|%d|%d|%d|%d|%d|%d|%s|", list, acl_type,
	  acl_name, active, maillist, grouplist, nfsgroup, publicflg, hidden, description);

  EXEC SQL DECLARE u_cursor CURSOR FOR
    SELECT UNIQUE u.login FROM users u, imembers i, list l
    WHERE l.list_id = :lid AND l.list_id = i.list_id AND
    i.member_type = 'USER' AND i.member_id = u.users_id;
  EXEC SQL OPEN u_cursor;
  while (1)
    {
      EXEC SQL FETCH u_cursor INTO :login;
      if (sqlca.sqlcode)
        break;
      fprintf(out, "%s%s", maybecomma, strtrim(login));
      maybecomma = ",";
    }
  EXEC SQL CLOSE u_cursor;

  EXEC SQL DECLARE k_cursor CURSOR FOR
    SELECT UNIQUE s.string FROM strings s, imembers i, list l
    WHERE l.list_id = :lid AND l.list_id = i.list_id AND
    (i.member_type = 'KERBEROS' OR i.member_type = 'STRING')
    and i.member_id = s.string_id;
  EXEC SQL OPEN k_cursor;
  while (1)
    {
      EXEC SQL FETCH k_cursor INTO :principal;
      if (sqlca.sqlcode)
	break;
       fprintf(out, "%s%s", maybecomma, strtrim(principal));
       maybecomma = ",";
    }
  EXEC SQL CLOSE k_cursor;

  fprintf(out, "|%s\n", modtime);
}

