/* Compute the number of business days needed to respond to a PR.
   Copyright (C) 1993 Free Software Foundation, Inc.
   Contributed by Tim Wicinski (wicinski@barn.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, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include "gnats.h"
#include <time.h>

#define BDAY_START 8
#define BDAY_END 17
#define BWEEK_START 1
#define BWEEK_END 5

#define SECONDS_DAY 86400	/* 24 * 60 * 60 */
#define SECONDS_HOUR 3600	/* 60 * 60 */

struct tm *
get_response_time (rtime, response_buf)
     int rtime;
     char *response_buf;
{
  struct tm *t;
  long seconds;
  int err, wday, hour, offhours;
  char *p;

  if (response_buf == NULL)
    return (struct tm *)NULL;

  seconds = time (0);
  t = localtime (&seconds);

  wday = t->tm_wday;
  hour = t->tm_hour;

  offhours = 24 - (BDAY_END - BDAY_START);

  /* Round it out.  */
  err = 60 - t->tm_min;
  if (err <= 30) 
    {
      seconds += (err * 60);
      hour++;
    }
  else
    seconds -= (t->tm_min * 60);

  /* FIXME - This will compute the response time, but it is a bit 
     overwrought with bloat.  This can be trimmed down.  */

  /* Check when the bug report arrived; if PR arrives before bweek starts,
     add time until start of business week.  */
  while (rtime >= 0)
    {
      /* Add up here, to the end of the first day, the number of days until
	 the bweek starts, and then the hours until the bday begins.  */
      if (wday < BWEEK_START)
	{
	  seconds += ((24 - hour + BDAY_START) * SECONDS_HOUR) +
	    ((BWEEK_START - wday) * SECONDS_DAY);
	  wday = BWEEK_START;
	  hour = BDAY_START;
	}

      /* Also add in the hours from the night before.  do this before 
	 checking for end of week in case bug is marked at WEEK_END,
	 after BDAY_END (ie, after friday at 5). */
      if (hour >= BDAY_END)
	{
	  seconds += (((24 - hour) + BDAY_START) * SECONDS_HOUR);
	  hour = BDAY_START;
	  wday++;
	}

      /* Same as above, but the end of week is slightly different.  */
      if (wday > BWEEK_END)
	{
	  /* Same as addition above, but compute end of week and beginning of
	     week seperately for now (offdays?). */
	  seconds += ((24 - hour) * SECONDS_HOUR) +
	    ((wday - BWEEK_END - 1) * SECONDS_DAY) +
	    (BWEEK_START * SECONDS_DAY) +
	    (BDAY_START * SECONDS_HOUR);
	  wday = BWEEK_START;
	  hour = BDAY_START;
	}

      /* If PR arrives before bday starts, then do some simple rounding up to
	 the beginning of the business day. */
      if (hour < BDAY_START)
	{
	  seconds += (BDAY_START - hour) * SECONDS_HOUR;
	  hour = BDAY_START;
	}

      /* Actual computing of the business hours. Take into consideration that
	 some response times might be long. (Which is why this is all in a
	 loop.) */

      err = BDAY_END - hour;
      if (err > 0 && err < rtime)
	{
	  /* The # of hours is more than today.  */
	  rtime -= err;

	  /* Skip to the next day.  */
	  seconds += (err * SECONDS_HOUR) +
	    (offhours * SECONDS_HOUR);
	  hour = BDAY_START;
	  wday++;
	}
      else
	{
	  seconds += rtime * SECONDS_HOUR;

	  /* escape condition */
	  rtime = -1;
	}

    }

  strcpy (response_buf, ctime (&seconds));

  /* Strip off the line feed.  */
  p = (char *) strrchr (response_buf, '\n');
  if (p)
    *p = '\0';

  return t;
}
