/* proclog.c -- Eat Log and update the systems tables.
 *
 * This file is part of TUA.
 * 
 *   Copyright (C) 1991,96  Lele Gaifax
 *
 *   This program 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 of the license, or (at
 *   your option)
 *   any later version.
 *
 *   This program 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 this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

#include "tua_4_taylor.h"

#if TAYLOR_UUCP

static void EXFUN (proc_uux, (struct log *));
static void EXFUN (proc_uuxqt, (struct log *));
static void EXFUN (proc_uucico, (struct log *));

static void
adjust_failed_calls (process_status_t * p)
{
  if (p->Status == TUUS_CALLING)
    {
      p->System->Calls++;
      p->System->CallsFAIL++;
    }
  else if (p->Status != TUUS_NONE && p->System)
    {
      p->System->Calls++;
      p->System->CallsSTOPPED++;
    }
}

int
DEFUN_VOID (read_log_log)
{
  int log_status;
  FILE * fp;
  char FileName[LPNMAX];
  struct log entry;
  int first_line = TRUE;    

  debug_filename(FileName);
  
#ifdef DEBUG
  if (be_verbose)
    fputs ("\nProcessing Log:\n", stderr);
#endif
  
  sprintf (FileName, "%s/%s", logs_prefix_path_opt, LOG_NAME);

  if ((fp = fopen (FileName, "r")) == (FILE *) NULL)
    {
      LOG ("cannot open %s", FileName);
      return ERROR;
    }

  entry.Owner = entry.System = entry.User = entry.PortName = entry.Command = 0;

  while ((log_status = GetLog (fp, &entry)) != EOF)
    {
      if (just_some_system_opt)
	{
	  system_rec_t * sr;
	  if ((sr = search_system (entry.System)) == (system_rec_t *) NULL || sr->Killed)
	    continue;
	}
      
      if (strcmp (entry.Owner, "uux") == 0)
	proc_uux (&entry);
      else if (strcmp (entry.Owner, "uuxqt") == 0)
	proc_uuxqt (&entry);
      else if (strcmp (entry.Owner, "uucico") == 0)
	proc_uucico (&entry);

      if (first_line && (StatStartingTime > entry.TimeStamp || StatStartingTime == 0.0))
	StatStartingTime = entry.TimeStamp;

      first_line = FALSE;
    }

  enquire_processes ((traverse_func_t) adjust_failed_calls);
  
  if (StatEndingTime < entry.TimeStamp)
    StatEndingTime = entry.TimeStamp;

  debug_end();
  
  fclose (fp);

  xfree (entry.Owner);
  xfree (entry.System);
  xfree (entry.User);
  xfree (entry.PortName);
  xfree (entry.Command);
  entry.Owner = entry.System = entry.User = entry.PortName = entry.Command = 0;

  return (log_status == EOF ? OK : ERROR);
}

static void
DEFUN (proc_uux, (entry),
       struct log * entry)
{
  if (do_command_report_opt)
    {
      char commandline[LINE_BUFFER_SIZE];
      user_rec_t *ur = insert_user (entry->User);
      day_rec_t *dr = insert_day (julian_to_d (entry->TimeStamp, 0));
      system_rec_t *sr = insert_system (entry->System);
      command_rec_t *cr;
      
      sprintf (commandline, "(%s) %s", entry->System, entry->Command);
      
      if (!ur->Killed)
	{
	  cr = insert_command (&ur->Commands, commandline);
	  cr->Number++;
	}
      
      cr = insert_command (&dr->Commands, commandline);
      cr->Number++;

      if (!sr->Killed)
	{
	  cr = insert_command (&sr->Commands, entry->Command);
	  cr->Number++;
	}
    }
}

static void
DEFUN (proc_uuxqt, (entry),
       struct log * entry)
{
  char * command;

  if (strbegcmp (entry->Command, "Executing ") == 0)
    {  
      strtok (entry->Command, "(");
      command = savestring (strtok (NULL, ")"));

      xfree (entry->Command);
      entry->Command = command;
      proc_uux (entry);
    }
}

static void
DEFUN (proc_uucico, (entry),
       struct log * entry)
{
  system_rec_t * sr = NULL;		/* just to stop gcc complaining about uninitialized vars */
  process_status_t * pr = insert_process (entry->ProcessId);
  
  if (strbegcmp (entry->Command, "Incoming call") == 0)
    {
      pr->LoginPassed = TRUE;
      pr->WhoIsPaying = REMOTE_SYSTEM;
      pr->Status = TUUS_INCOMING;
      return;
    }

  if (strcmp (entry->System, "-"))
    {
      sr = insert_system (entry->System);
      pr->System = sr;
    }
  else
    {
      debug_message ("Bad system name: '-'");
      return;
    }

  if (strbegcmp (entry->Command, "Calling system") == 0)
    {
      Date_t d;
      Time_t t;
      int phone_tb;

      julian_to_dt (entry->TimeStamp, &d, &t);
      phone_tb = get_phone_timeband (d.DayOfWeek, t.Hour, t.Min);

      sr->LastConnection = entry->TimeStamp;

      if (sr->PhoneCall == 0)
	system_alloc_phone_costs (sr);

      sr->PhoneCall[phone_tb]++;

      pr->LoginPassed = FALSE;
      pr->WhoIsPaying = LOCAL_SYSTEM;
      pr->Status = TUUS_CALLING;
    }
  else if (strbegcmp (entry->Command, "Errors:") == 0)
    {
      pr->Status = TUUS_ERROR;
    }
  else if (strbegcmp (entry->Command, "Handshake successful") == 0)
    {
      if (pr->Status == TUUS_INCOMING)
	{
	  pr->LoginPassed = TRUE;
	  pr->Status = TUUS_HANDSHAKE;
	  sr->LastConnection = entry->TimeStamp;
	}
    }
  else if (strbegcmp (entry->Command, "Login successful") == 0)
    {
      pr->LoginPassed = TRUE;
      pr->Status = TUUS_LOGIN;
    }
  else if (strbegcmp (entry->Command, "Call complete") == 0)
    {
      char * secs;
      long seconds;
      extern long EXFUN(atol, (CONST char *));

      strtok (entry->Command, "(");
      secs = strtok (NULL, " ");
      seconds = atol (secs);
      sr->TimeConnect += seconds;

      sr->TimePayedBy[pr->WhoIsPaying] += seconds;
      sr->Calls++;
      if (pr->Status != TUUS_ERROR)
	{
	  sr->CallsOK++;

	  if (pr->WhoIsPaying == LOCAL_SYSTEM)
	    sr->CallsOut++;
	  else
	    sr->CallsIn++;
	}
      else
	{
	  if (pr->LoginPassed)
	    sr->CallsSTOPPED++;
	  else
	    sr->CallsFAIL++;
	}
      
      kill_process (pr->ProcessId);
    }
  else if (strbegcmp (entry->Command, "Sending") == 0)
    {
      pr->Status = TUUS_SENDING;
    }
}
	
#endif /* TAYLOR_UUCP */
