/*
 * chanstat.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 "settings.h"
#include "bottypes.h"
#include "globals.h"
#include "dl.h"

#define UNKNOWN_OWNER "\02???\02"

void m_chanstat(char *a);

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

  snprintf(dl->help, MAX_COMMAND_HELP_LEN,
	   "/msg %s CHANSTAT #channel    only stat for #channel\n"\
	   "/msg %s CHANSTAT 4           <=4 visits/week\n"\
	   "/msg %s CHANSTAT 0 10        0-10 visists/week\n"
	   , BOT_NAME, BOT_NAME, BOT_NAME);
  snprintf(dl->summary, MAX_COMMAND_SUMMARY_LEN,
	   "Give stats and timestamps for channels.");
  dl->level = 950;
#if 0
  dl->func = m_chanstat;
#else
  dl->func = (void (*)(char*)) DL_sym(dl->val, "m_chanstat");
#endif
  return 1;
}

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

MODULE_PUBLIC void m_chanstat(char *a)
{
  int i;
  char *owner_str;
  struct dbaseuser *owner_d;
  struct chanopts *c;
  char channel[CHANNELLEN+1];
  char to_str[CHANNELLEN+1];
  char tmp[256];
  char none[10];
  ListElem *el;
  time_t t_now = time(NULL);
  struct tm *tm_;
  int from, to, nr;
  float j;
  struct chantype *ct;

  struct dbaseuser *db;
  db = sender_au->dbuser;
  if(db) {
    log("From: %s chanstat [%s]\n", db->nick, a);
  } else
    return;
  if(!is_oper()) {
    say_sender("You are not an Oper.");
    log("To: %s Is not an Oper\n", db->nick);
    return;
  }

  i=0;
  /*
    This function MUST be fixed and clean up everything from
    all channels, and in all lists.
  */
  strncpy(channel,getword(a,&i),CHANNELLEN);
  channel[CHANNELLEN] = '\0';
  if(!strlen(channel)) {
    say_sender( "You forgot to type the #channel");
    say_sender_( "/msg %s CHANSTAT #channel    only stat for #channel", BOT_NAME);
    say_sender_( "/msg %s CHANSTAT 4           <=4 visits/week", BOT_NAME);
    say_sender_( "/msg %s CHANSTAT 0 10        0-10 visists/week", BOT_NAME);
    return;
  }
  c = findchannel(channel);
  if(c) {
    say_sender_("Channel stats for: %s", channel);

    owner_d = finduserfromid(c->owner);
    if(owner_d) {
      owner_str = owner_d->nick;
    } else {
      strcpy(none, UNKNOWN_OWNER);
      owner_str = none;
    }
    say_sender_("Original founder: %s", owner_str);

    owner_d = finduserfromid(c->created_by);
    if(owner_d) {
      owner_str = owner_d->nick;
    } else {
      sprintf(none, "%s (id=%d)", UNKNOWN_OWNER, c->created_by);
      owner_str = none;
    }
    say_sender_("Added by operator: %s", owner_str);

    if(c->type) {
      ct = NULL;
      el = GetHead(chantype_list);
      while(el) {
	ct = (struct chantype *)el->data;
	if(ct->id == c->type) {
	  break;
	}
	el = GetSucc(el);
      }
      if(el) {
	say_sender_("Channeltype is: %d [%s]", ct->id, ct->name);
      } else {
	say_sender_("Channeltype is: %d (undefined)", ct->id);
      }
    } else {
      say_sender("Channeltype is: (not set)");
    }

    if(c->suspended) {
      char date_str[32+1];
      struct dbaseuser *d;
      d = finduserfromid(c->suspend_who);
      tm_ = localtime(&c->suspend_time);
      strftime(date_str, 32, "%c", tm_);
      sprintf(tmp, "Channel is suspended by %s (%s) Reason: [%s]", (d ? d->nick : "???"),
	      date_str, (c->suspend_reason ? c->suspend_reason : "???"));
      say_sender( tmp);
    }

    if(c->first_joined > 0) {
      tm_ = localtime(&c->first_joined);
      strftime(tmp, 60, "First Join: %c", tm_);
      say_sender( tmp);
    } else {
      say_sender( "First Join: NEVER!");
    }
    if(c->last_joined > 0) {
      tm_ = localtime(&c->last_joined);
      strftime(tmp, 60, "Last Join:  %c", tm_);
      say_sender( tmp);
    } else {
      say_sender( "Last Join:  NEVER!");
    }
    say_sender_("Nr of joins:  %d", c->nr_joined);
	
    if(c->first_joined && (c->nr_joined>1)) {
      j = ( ((float)c->nr_joined * (float)(3600*24*7)) /
	    ((float)(t_now - c->first_joined)));
      say_sender_("Average:   %7.2f joins/week", j);
    }
    return;
  }
    
  if(channel[0]=='#') {
    say_sender( "Couldn't find channel");
    return;
  }
  if(!isdigit(channel[0])) {
    say_sender( "Value should be a digit!");
    return;
  }
  from = atoi(channel);

  nr = 0;
  strncpy(to_str,getword(a,&i),NICKLEN);
  to_str[NICKLEN] = '\0';
  if(!strlen(to_str)) {
    to = from;
    from = 0;
    say_sender_("Channels with less than %d joins/week", to);
    say_sender_("%-15s %6s %9s", "Channel", "Joins", "Average");
    el = GetHead(channel_list);
    if(el) {
      c = (struct chanopts *)el->data;
      if( !c->first_joined || (c->nr_joined<=1)) {
	j = 0;
      } else {
	j = ( ((float)c->nr_joined * (float)(3600*24*7)) /
	      ((float)(t_now - c->first_joined)));
      }
      if( (((int)(j+0.5))>from)  && (((int)(j+0.5))<to) ) {
	say_sender_("%-15s %6d %7.2f", c->channel, c->nr_joined, j);
	nr++;
      }
      el = GetSucc(el);
    }
    say_sender_("%d channels.", nr);
    say_sender( "End of list.");
    return;
  }
  if(!isdigit(to_str[0])) {
    say_sender( "<To> value should be a digit!");
    return;
  }
  to = atoi(to_str);

  if(to >= from) {
    say_sender_("Channels with %d-%d joins/week", from, to);
    say_sender_("%-15s %6s %9s", "Channel", "Joins", "Average");
    el = GetHead(channel_list);
    while(el) {
      c = (struct chanopts *)el->data;
      if( !c->first_joined || (c->nr_joined<=1)) {
	j = 0;
      } else {
	j = ( ((float)c->nr_joined * (float)(3600*24*7)) /
	      ((float)(t_now - c->first_joined)));
      }
      if( (((int)(j+0.5))>from)  && (((int)j+0.5)<to) ) {
	say_sender_("%-15s %6d %7.2f", c->channel, c->nr_joined, j);
	nr++;
      }
      el = GetSucc(el);
    }
    say_sender_("%d channels.", nr);
    say_sender( "End of list.");
    return;
  } else {
    say_sender( "<To> should be greater than <From>");
  }
  return;
}
