/* Give stats on PRs regarding their lifetime from open to closed state.
   Copyright (C) 1994, 1995, 2002 Free Software Foundation, Inc.
   Contributed by Brendan Kehoe (brendan@cygnus.com).

This file is part of GNU GNATS.

GNU GNATS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU GNATS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU GNATS; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA.  */

/* Initial version, when complete dissect it and put functionality into
   the server, and make this a bare client using that design to extend
   the possibilities of what we're adding.  */

#include "gnats.h"
#include "query.h"

void usage (), version ();

/* The name this program was run with.  */
char *program_name;

typedef struct _times
{
  int days;
  int hours;
} Times;

struct option long_options[] =
{
  {"help", 0, NULL, 'h'},
  {"database", 1, NULL, 'd'},
  {"version", 0, NULL, 'V'},
  {NULL, 0, NULL, 0}
};

Times *
time_diff_2 (start, stop)
     time_t start, stop;
{
  Times *t = (Times *) xmalloc (sizeof (Times));
  time_t diff = stop - start;
  time_t days, hours;

  days = (diff / 3600) / 24;
  diff -= (days * 86400); /* days * 60 * 60 * 24 */
  hours = diff / 3600;

  t->days = days;
  t->hours = hours;
  return t;
}

time_t
got_closed (p)
     char *p;
{
  time_t t;
  char *final1, *final2;
  char *c;

  /* Skip ahead to the last time it was closed.  */
  final1 = p;
  do
    {
      final2 = final1;
      final1 = strstr (final2, "-closed\n");
      if (final1)
	final1 += 8;
    } while (final1);
  if (! final2)
    return (time_t)0;

  /* Grab the date, and return the time it represents.  */
  final1 = strstr (final2, "When: ");
  if (! final1)
    return (time_t)0;
  c = strchr (final1 + 6, '\n');
  if (c)
    *c = '\0';

  return get_date (final1 + 6, NULL);
}

void
do_stat (p)
     char *p;
{
  char *path;
  ErrorDesc err;

  path = lookup_pr_path (p, &err);

  if (path != NULL)
    {
      /* XXX ??? Check the final argument */
      if (get_pr (path, p, 0))
	{
	  time_t start = get_date (field_value (ARRIVAL_DATE), NULL);
	  time_t stop = got_closed (field_value (AUDIT_TRAIL));
	  Times *t;

	  /* We don't care about ones that had no closed status in its
	     audit trail.  */
	  if (!start || !stop)
	    {
	      free (path);
	      return;
	    }

	  t = time_diff_2 (start, stop);
	  /* XXX do real stuff here */
	  printf ("%d %2d\n", t->days, t->hours);
	  free (t);
	}
      else
	{
	  fprintf (stderr, "Unable to read PR %s\n", p);
	}
      free (path);
    }
}

void
do_category (c)
     char *c;
{
  PR *pr;

  for (pr = pr_chain; pr != NULL ; pr = pr->next)
    {
      if ((strcmp (field_value (pr, CATEGORY->index), c) == 0)
	  && (check_state_type (field_value (pr, STATE->index), "closed")))
	{
	  char *path;
	  asprintf (&path, "%s/%s", c, field_value (pr, NUMBER->index));
	  do_stat (path);
	  free (path);
	}
    }
}

int
main (argc, argv)
     int argc;
     char **argv;
{
  int optc;
  program_name = basename (argv[0]);
  char *database = NULL;
  ErrorDesc err;

  while ((optc = getopt_long (argc, argv, "hVd:",
			      long_options, (int *) 0)) != EOF)
    {
      switch (optc)
	{
	case 'd':
	  database = optarg;
	  break;

	case 'V':
	  version ();
	  exit (0);
	  break;

	case 'h':
	  usage (0);
	  break;

	default:
	  usage (1);
	}
    }

  if (optind == argc || optind >= argc)
    usage (1);

  if (init_gnats (program_name, database, &err) != 0)
    {
      client_print_errors (err);
      exit (1);
    }

  index_chain = get_pr_chain (&err);
  if (index_chain == NULL)
    {
      client_print_errors (err);
      exit (1);
    }

  if (optind == argc)
    /* nothing */ ;
  else
    while (optind < argc)
      do_category (argv[optind++]);

#if 0
  /* One approach: */
  printf ("Category         # bugs         Avg Age  Max Age  Min Age\n");
  printf ("                                  dy hr    dy hr    dy hr\n\n");

  printf ("%-16s %4d           %4d %02d  %4d %02d  %4d %02d\n", 
	  c, cnt[c], avgd, avgh, maxd, maxh, mind, minh);
#endif

  exit (0);
}

void
usage (x)
  int x;
{
  fprintf (stderr, "Usage: %s [-d database_name] category [category...]\n", program_name);
  exit (x);
}

void
version (void)
{
  printf ("pr-stat %s\n", version_string);
}
