/*
 * whoison.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"

void m_whoison(char *a);

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

  snprintf(dl->help, MAX_COMMAND_HELP_LEN,
	   "/msg %s WHOISON <#channel>\nShow who is on a channel. The channel could be a pattern (if level is high enough), but is dangerous since it will cause a major flood.\n"
	   , BOT_NAME);
  snprintf(dl->summary, MAX_COMMAND_SUMMARY_LEN,
	   "Show who is on a channel");
  dl->level = 950;
#if 0
  dl->func = m_whoison;
#else
  dl->func = (void (*)(char*)) DL_sym(dl->val, "m_whoison");
#endif
  return 1;
}

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


static void inc_channel(struct chan_stat *list, char *channel)
{
  struct chan_stat *c, *lc, *newc;
  lc = list;
  c = list->next;
  while(c) {
    if(strcasecmp(c->channel, channel)==0) {
      c->count++;
      return;
    }
    lc = c;
    c = c->next;
  }
  newc = (struct chan_stat *)Malloc(sizeof(struct chan_stat));
  if(newc) {
    strncpy(newc->channel, channel, CHANNELLEN);
    newc->channel[CHANNELLEN] = '\0';
    newc->count = 1;
    newc->next = NULL;
    lc->next = newc;
  }
  return;
}



MODULE_PUBLIC void m_whoison(char *a)
{
  struct chan_stat first_chanstat;
  struct chan_stat *cs, *cstmp;
  struct activeuser *u;
  struct chanopts *co;
  struct chanmod *c;
  ListElem *el;
  char buffer[512], maxbuffer[512], channel[NICKLEN+2];
  int channels, i, max_count, matches;

  struct dbaseuser *db;
  db = sender_au->dbuser;
  if(db) {
    log("From: %s whoison [%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;
  strncpy(channel,getword(a,&i),NICKLEN+1);
  channel[NICKLEN+1] = '\0';
  if(!strlen(channel)) {
    say_sender( "You forgot the search pattern.");
    say_sender_( "/msg %s WHOISON *pattern*", BOT_NAME);
    return;
  }

  /* first post is not used actually */
  first_chanstat.next = NULL;
  first_chanstat.count = 0;
  first_chanstat.channel[0] = '\0';

  matches = 0;

  el = GetHead(auser_list);
  /*
  if(db->globalauth >= 998) {
  */
    while(el) {
      u = (struct activeuser *)el->data;
      c = u->chanmodes;
      while(c) {
	if( !match(channel, c->channel) ) {
	  inc_channel(&first_chanstat, c->channel);
	  if(matches++ < 100) {

	    /* this will only detect people who are authed and have
	       modes set on the channel. Change this.
	    */
	    sprintf(buffer, "%-15s  %s%s", c->channel,
		    ((c->mode&(1<<('o'-'a'))) ? "@" : ""), u->nick);
	    say_sender(buffer);
	    if(matches == 100) {
	      say_sender("Warning: Stop due to 100 matches.");
	    }
	  }
	}
	c = c->next;
      }
      el = GetSucc(el);
    }
#if 0
  } else {
    while(el) {
      u = (struct activeuser *)el->data;
      c = u->chanmodes;
      while(c) {
	if( !strcasecmp(channel, c->channel) ) {
	  inc_channel(&first_chanstat, c->channel);
	  matches++;
	  sprintf(buffer, "%s", u->nick);
	  say_sender(buffer);
	}
	c = c->next;
      }
      el = GetSucc(el);
    }
  }
#endif
  channels = 0;
  if(matches) {
    max_count = 0;
    cs = first_chanstat.next;
    while(cs) {
      channels++;
      if(cs->count > max_count) {
	max_count = cs->count;
	sprintf(maxbuffer, "%-15s  %d users.", cs->channel, cs->count);
      }
      co = findchannel(cs->channel);
      if(co) {
	sprintf(buffer, "%-15s  %d users. (%d)", cs->channel, cs->count, co->current_joined);
      } else {
	sprintf(buffer, "%-15s  %d users.", cs->channel, cs->count);
      }
      say_sender(buffer);
      cstmp = cs;
      cs = cs->next;
      Free(cstmp);     /* free it at once */
      cstmp = NULL;
    }
    sprintf(buffer, "Largest channel is: %s", maxbuffer);
    say_sender(buffer);
  }
  sprintf(buffer, "Found %d matches at %d channels", matches, channels);
  say_sender(buffer);
  return;
}
