/**********************************************************************
 * PTlink IRC Services is (C) CopyRight PTlink IRC Software 1999-2005 *
 *                     http://software.pt-link.net                    *
 * This program is distributed under GNU Public License               *
 * Please read the file COPYING for copyright information.            *
 **********************************************************************

  Description: botserv core module

 *  $Id: botserv.c,v 1.15 2005/10/18 16:25:06 jpinto Exp $
*/

#include "chanserv.h"
#include "module.h"
#include "path.h"
#include "my_sql.h"
#include "dbconf.h"
#include "lang/common.lh"

/* module, version, description */
SVS_Module mod_info =
{"botserv", "1.2", "botserv core module" };

#define DB_VERSION	1

/*  ChangeLog:
  1.2 - #65: Fixed Chan Drop & BotServ
  1.1 - #18 - bots are not getting chanmode +o on join
  1.0 - 0000315: created botserv core module and basic functionalities
*/ 

/** functions/events we require **/
/* void (*FunctionPointer)(void);*/
int mysql_connection;
ServiceUser* (*chanserv_suser)(void);
static int irc;
static int e_chan_delete;

MOD_REQUIRES
  MOD_FUNC(dbconf_get_or_build)
  MOD_FUNC(irc)
  MOD_FUNC(mysql_connection)
  MOD_FUNC(chanserv_suser)
  MOD_FUNC(e_chan_delete)
MOD_END

/* functions we provide */
ServiceUser* botserv_suser(void);
static int e_bot_introduce;

MOD_PROVIDES
  MOD_FUNC(e_bot_introduce)
  MOD_FUNC(botserv_suser)
MOD_END

/* core events */
void ev_bs_new_server(IRC_Server* nserver, IRC_Server* from);
int sql_upgrade(int version, int post);

/* commands */
void bs_unknown(IRC_User* s, IRC_User* t);

int ev_botserv_chan_delete(u_int32_t *snid, void *dummy);

ServiceUser bsu;
int bs_log;

/* Local config */
static char* Nick;
static char* Username;
static char* Hostname;
static char* Realname;
static char* AdminRole;
static int DefaultExpireTime;
static int MaxChansPerBot;
DBCONF_PROVIDES
  DBCONF_WORD(Nick, 	"BotServ", "Botserv service nick")
  DBCONF_WORD(Username, "Services", "Botserv service username")
  DBCONF_WORD(Hostname, "PTlink.net", "Botserv service hostname")
  DBCONF_STR(Realname, "Botserv Service", "Botserv service real name")
  DBCONF_WORD_OPT(AdminRole,"Admin", "Botserv admin role")
  DBCONF_TIME(DefaultExpireTime, "0d", "Botserv default expire time")
  DBCONF_INT(MaxChansPerBot, "1",
    "The max number of channels a bot can be assigned to")  
DBCONF_END

/* this is called before load and at services rehash */
int mod_rehash(void)
{
  if(dbconf_get_or_build(mod_info.name, dbconf_provides) < 0 )
  {
    errlog("Error reading dbconf!");
    return -1;
  }
  return 0;
}
int mod_load(void)
{
  /* first try to open the log file */
  bs_log = log_open("botserv","botserv");

  if(bs_log < 0)
  {
    errlog("Could not open botserv log file!");
    return -1;
  }
  
  if(sql_check_inst_upgrade(mod_info.name, DB_VERSION, sql_upgrade) < 0)
	  return -4;

  /* Create botserv user */
  bsu.u = irc_CreateLocalUser(Nick, Username, Hostname, Hostname,
    Realname,"+ro");

  irc_AddUMsgEvent(bsu.u, "*", bs_unknown); /* any other msg handler */

  /* Server events - to introduce local bots */
  irc_AddEvent(ET_NEW_SERVER, ev_bs_new_server);
  
  /* botserv needs to getout when channels are deleted */
  mod_add_event_action(e_chan_delete,
  	(ActionHandler) ev_botserv_chan_delete);
          
   
  return 0;
}

void mod_unload(void)
{
  MYSQL_RES *res;
  MYSQL_ROW row;
  
  /* remote pseudo users before disconnecting BotServ */
  res = sql_query("SELECT nick FROM botserv");

  while((row = sql_next_row(res)))
    {
      IRC_User *user = irc_FindUser(row[0]);
      if(user)
	      irc_QuitLocalUser(user, "Removing service");
    }
  sql_free(res);
  
  /* remove botserv and all associated events */
  irc_QuitLocalUser(bsu.u, "Removing service");

}

/* to return the nickserv client */
ServiceUser* botserv_suser(void)
{
	  return &bsu;
}

void bs_unknown(IRC_User* s, IRC_User* t)
{
  send_lang(t, s, UNKNOWN_COMMAND, irc_GetLastMsgCmd());
}

/* this is called when a new server is introduced,
we just care for the first server when services connect to the hub 
so that we create the bots and join them to their channels
*/
void ev_bs_new_server(IRC_Server* nserver, IRC_Server *from)
{
  static int already_loaded = 0;
  MYSQL_RES *res;
  MYSQL_ROW row;

  if (already_loaded)
    return;
	
  res = sql_query("SELECT nick,username,publichost,realname,bid FROM botserv");

  while((row = sql_next_row(res)))
  {
    MYSQL_RES *res_chan;
    MYSQL_ROW row_chan;
    IRC_User *user;
    u_int32_t bid = atoi(row[4]);
    user = irc_CreateLocalUser(row[0], row[1], row[2], row[2], row[3], "+r");
    mod_do_event(e_bot_introduce, &bid, NULL);
    res_chan = sql_query("SELECT c.name FROM chanserv c, botserv_chans bc "
      "WHERE bc.bid=%d AND c.scid=bc.scid", bid);
    while((row_chan = sql_next_row(res_chan)))
    {
      IRC_Chan *chan = irc_ChanJoin(user, row_chan[0], 0);
      irc_ChanMode(bsu.u, chan, "+ao %s %s", user->nick, user->nick);
    }
    sql_free(res_chan);
  }

  sql_free(res);
	
  already_loaded = -1;
}

/* this version takes care of sql upgrades */
int sql_upgrade(int version, int post)
{
	return 1;
}

int ev_botserv_chan_delete(u_int32_t *scid, void *dummy)
{
  sql_execute("DELETE FROM botserv_chans WHERE scid=%d", *scid);
  return 0;
}



syntax highlighted by Code2HTML, v. 0.9.1