/*
 * status.c
 * (C) Christian Magnusson 2000, Email: d1mag@dtek.chalmers.se
 * This program is copyright, and covered by the Gnu Public License.
 * The Q bot.
 */

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

#include <sys/types.h>
#include <unistd.h>

#include "settings.h"
#include "bottypes.h"
#include "globals.h"
#include "dl.h"

void m_status(char *a);

MODULE_PUBLIC int _init_status(void *a, void *b)
{
  dl_command_entry_t *dl = a;
  if(!a) return 0;

  snprintf(dl->help, MAX_COMMAND_HELP_LEN,
	   "/msg %s STATUS\nReturn some status about the net\n", BOT_NAME);
  snprintf(dl->summary, MAX_COMMAND_SUMMARY_LEN,
	   "Return some status about the net");
  dl->level = 950;
#if 0
  dl->func = m_status;
#else
  dl->func = (void (*)(char*)) DL_sym(dl->val, "m_status");
#endif
  return 1;
}

MODULE_PUBLIC int _remove_status(char *a, char *b)
{
  remove_command("status");
  return 1;
}

int mystat(char *out);

MODULE_PUBLIC void m_status(char *a)
{
  ListElem *el;
  char buffer[1024];
  char tmp[61];
  int users, nr_channels, authed, active;
  struct tm *tm_;
  time_t tnow;
  struct dbaseuser *db = sender_au->dbuser;

  if(!is_oper()) {
    say_sender("You are not an Oper.");
    return;
  }
  users = 0;
  el = GetHead(dbuser_list);
  while(el) {
    users++;
    el = GetSucc(el);
  }
  nr_channels = 0;
  el = GetHead(channel_list);
  while(el) {
    nr_channels++;
    el = GetSucc(el);
  }
  authed = 0;
  active = 0;
  el = GetHead(auser_list);
  while(el) {
    active++;
    if(((struct activeuser *)el->data)->userid) {
      authed++;
    }
    el = GetSucc(el);
  }
  say_sender_("Registered Users: %d", users);
  say_sender_("Registered Channels: %d", nr_channels);
  say_sender_("Currently AUTH'ed Users: %d (%4.1f%%)", authed,
	      100.0 * ((float)authed / (float)active));
  say_sender_("Currently Active Users: %d", active);
  tm_ = localtime(&max_users_time);
  strftime(buffer, 60, "(%c)", tm_);
  say_sender_("Max Active Users: %d %s", max_users, buffer);
  if(db->globalauth >= 990) {
    if(mystat(buffer)) dumpmessage_u(sender_au, buffer);
  }
#ifdef DMALLOC
  say_sender_("Memory allocated: %d", tot_malloc);
#endif

  tm_ = localtime(&startup_time);
  strftime(buffer, 60, "Time Reboot: %c", tm_);
  say_sender( buffer);
    
  tnow = time(NULL);
  tnow -= startup_time;
  tm_ = gmtime(&tnow);
  strftime(tmp, 60, "%H:%M:%S", tm_);
  /* does not print uptime over 1 year correct */
  sprintf(buffer, "Uptime: %d days %s", tm_->tm_yday, tmp);
  say_sender( buffer);
  return;
}

int mystat(char *out)
{
  static unsigned long last_cl = 0;
  static time_t last_cltime = 0;
  unsigned long cl;
  time_t t;
  char tmp[1024+1];
  char fname[80];
  FILE *fp;
  int len = 0, i = 0;
  int pid = getpid();
  unsigned long utime, stime, msize, start_time;
  time_t runtime;
  char *s;

  //  pid = 20921;
  if(!out) return len;
  out[0] = '\0';
  sprintf(fname, "/proc/%d/cpu", pid);
  fp = fopen(fname, "r");
  if(!fp) {
    return 0;
  }
  if(!fgets(tmp, 1024, fp)) {
    fclose(fp);
    return len;
  }
  fclose(fp);

  if(strncmp(tmp, "cpu", 3)) {
    return len;
  }
  if(sscanf(tmp, "cpu %lu %lu", &utime, &stime) != 2) {
    return len;
  }
  len += sprintf(&out[len], "CPU-time: %02d:%02d:%02d,%02d\n",
		 (int)((utime+stime)/360000),
		 (int)(((utime+stime)%360000)/6000),
		 (int)(((utime+stime)%6000)/100),
		 (int)((utime+stime)%100));

  sprintf(fname, "/proc/%d/stat", pid);
  fp = fopen(fname, "r");
  if(!fp) {
    return len;
  }
  if(!fgets(tmp, 1024, fp)) {
    fclose(fp);
    return len;
  }
  fclose(fp);
  i = 0;
  s = tmp;
  while(i<21) {
    s = strchr(s, ' ');
    if(!s) break;
    i++;
    s++;
  }
  if(!s) {
    return len;
  }
  if(sscanf(s, "%lu %lu", &start_time, &msize) != 2) {
    return len;
  }
  len += sprintf(&out[len], "Memory: %d kB\n", (int)(msize/1024));
  runtime = time(NULL)-start_time;
  len += sprintf(&out[len], "Avg. CPU%%: %.2f%%\n", 10000.0*((float)(utime+stime))/(float)runtime);

  t = time(NULL);
  cl = utime+stime;
  if(last_cl) {
    if((t-last_cltime) > 0) {
      len += sprintf(&out[len], "Last CPU%%: %.2f%% (%d sec.)\n",
		     ((float)(cl-last_cl))/(float)(t-last_cltime),
		     (int)(t-last_cltime));
    }
  }
  last_cl = utime+stime;
  last_cltime = t;
  return len;
}

