// MorgenGrauen MUDlib
//
// /std/hook_provider.c  - Hooksystem
//
// $Id: hook_provider.c 9453 2016-02-04 21:22:54Z Zesstra $

#pragma strong_types
#pragma save_types
#pragma no_clone
#pragma range_check
#pragma pedantic

#define NEED_PROTOTYPES
#include <hook.h>
#undef NEED_PROTOTYPES

// get the object fur closure <cl> (where the code is!)
#define GET_OBJECT(cl) get_type_info(cl,2)

// Struct describing one hook consumer. <cl> will be called when the hook is
// triggered. The lower <prio>, the earlier the consumer will be called.
// <type> is a consumertype, e.g. surveyor, listener etc. (see hook.h)
struct hook_entry_s {
  closure cl;
  int prio;
  int endtime;
  int type;
};

// Struct holding the consumers of one specific hook.
// the value arrays are guarenteed to exist, but may be empty.
struct hook_s {
  struct hook_entry_s *surveyors;
  struct hook_entry_s *hmods;
  struct hook_entry_s *dmods;
  struct hook_entry_s *listeners;
};

/* hook mapping
   the list of all offered hooks in the following structure:
   ([hookid: (<hook_s>), ...
   )]
*/
private nosave mapping hookMapping=([]);

protected void CleanHookMapping(int *hookids);

// Debugging - ggf. ueberschreiben
protected int h_dbg() {return 0;}

void HookTestOffer(int id, int stat){
  if(h_dbg()) {
      offerHook(id,stat);
  }
}

void HookTestTrigger(int id, mixed data){
  if(h_dbg()) {
      HookFlow(id,data);
  }
}

// NOTE: if you have the closure, you can call the lfun, even if it is
// private. Therefore access to this data should be restricted to
// this_object().
// These two functions should be used for debugging purposes.
protected mapping HCopyHookMapping(){
  return deep_copy(hookMapping);
}

protected mapping HCopyHookConsumers(int hookid){
  if(member(hookMapping,hookid)) {
      CleanHookMapping(({hookid}));
      return deep_copy(hookMapping[hookid]);
  }
  return 0;
}

// Ggf. zum Ueberschreiben.
int HConsumerTypeIsAllowed(int type, object consumer){
  return 1;
}

int HPriorityIsAllowed(int prio, object consumer){
  return 1;
}

// clean internal hook data structures of stale hook consumers.
protected void CleanHookMapping(int *hookids){
  // hooks enthaelt die aufzuraeumenden Hooks. Wenn kein Array -> alle Hooks
  if (!pointerp(hookids))
    hookids=m_indices(hookMapping);

  foreach(int hookid : hookids) { // alle Hooks
    struct hook_s hooks = hookMapping[hookid];
    if (!structp(hooks))
      continue;
    // ueber alle Consumertypen laufen
    foreach (string consumertype: H_CONSUMERNAMES)
    {
      // Yeah - compute struct lookup at runtime... ;-)
      struct hook_entry_s *consumers = hooks->(consumertype);
      // Hookeintraege / Consumer
      foreach(struct hook_entry_s h : &consumers) {
        // alle abgelaufenen Eintraege oder solche mit zerstoerten Objekten
        // nullen
        if (!h->cl || h->endtime < time() )
            h = 0;
      }
      // 0 noch rauswerfen.
      hooks->(consumertype) -= ({0});
    }
  }
}

protected void offerHook(int hookid, int offerstate)
{
  H_DMSG(sprintf("offerHook hookid %d offerstate %d\n",hookid,offerstate));
  if (hookid>0)
  {
      if (offerstate) {
          if (!member(hookMapping,hookid)) {
              struct hook_s hook = (<hook_s>
                  surveyors: ({}),
                  hmods: ({}),
                  dmods: ({}),
                  listeners: ({}) );
              hookMapping[hookid] = hook;
          }
      }
      else {
          if (member(hookMapping,hookid)) {
            m_delete(hookMapping,hookid);
          }
      }
  }
  H_DMSG(sprintf("  result %O\n",hookMapping));
}

// hookConsumerInfo() liefert Array von hook_entry_s zurueck. D.h. bei Abfrage
// von Objekten alle Closures dieses Objekts und jede davon erzeugt ein
// Element hook_entry_s im Ergebnisarray. Bei Abfrage von Closures hat das
// Array immer genau 1 oder kein Element.
// WARNING: whoever has a hook_entry_s can change/delete the hook!
//          NEVER return the original to an external caller!
// NOTE: whoever has the cl from hook_entry_s can call it, even if the lfun
//       is private (and this object the only one knowing it).
protected mixed * hookConsumerInfo(int hookid, object|closure consumer)
{
  closure filter_cl;

  if (!member(hookMapping,hookid))
    return ({});

  // Closure zum Filtern bestimmen - je nachdem, was gesucht wird.
  if (closurep(consumer))
  {
    filter_cl = function int (struct hook_entry_s h)
                { return h->cl == consumer
                         && h->endtime >= time(); };
  }
  else if (objectp(consumer))
  {
    filter_cl = function int (struct hook_entry_s h)
                { return GET_OBJECT(h->cl) == consumer
                         && h->endtime >= time(); };
  }
  else
  {
    return ({});
  }

  struct hook_s hook = hookMapping[hookid];
  struct hook_entry_s *result = ({});
  foreach (string consumertype: H_CONSUMERNAMES )
  {
    result += filter(hook->(consumertype), filter_cl);
  }
  return result;
}

int HIsHookConsumer(int hookid, mixed consumer) {
  return sizeof(hookConsumerInfo(hookid,consumer)) != 0;
}

int* HListHooks() {
  return m_indices(hookMapping);
}

int HUnregisterFromHook(int hookid, mixed consumer) {

  H_DMSG(sprintf("HUnregisterFromHook hookid %d consumer %O\n",hookid,consumer));
  if (objectp(consumer))
    consumer = symbol_function("HookCallback", consumer);
  if (!closurep(consumer))
    return 0;

  struct hook_entry_s *info = hookConsumerInfo(hookid,consumer);

  // it should never happen that a closure is registered more than once, i.e.
  // the result contains more than one element.
  if (sizeof(info)) {
      struct hook_entry_s h = info[0];
      h->cl = 0;
      H_DMSG(sprintf("  result %O\n", hookMapping));
      // the now invalid h will be cleaned up later.
      return 1;
  }
  return 0;
}

// surveyors are asked for registration permittance
protected int askSurveyorsForRegistrationAllowance(
                  struct hook_entry_s *surveyors, object consumer,int hookid,
                  int hookprio,int consumertype)
{
  H_DMSG(sprintf("askSurveyorsForRegistrationAllowance surveyors %O, "
        "consumer %O, hookid %d, hookprio %d, consumertype %d\n",
        surveyors,consumer,hookid,hookprio,consumertype));

  foreach(struct hook_entry_s surveyor : surveyors) {
    if (closurep(surveyor->cl) && surveyor->endtime >= time())
    {
      // surveyor hook gueltig.
      object sob = GET_OBJECT(surveyor->cl);
      if (!sob->HookRegistrationCallback(consumer, hookid,
                        this_object(), hookprio, consumertype))
        return 0;
    }
  }
  return 1;
}

int HRegisterToHook(int hookid, mixed consumer, int hookprio,
                       int consumertype, int timeInSeconds) {
  int ret, regtime;

  if (!closurep(consumer) && !objectp(consumer))
    raise_error(sprintf("Wrong argument %.50O to HRegisterToHook(): consumer "
          "must be closure or object.\n",consumer));

  if (!member(hookMapping, hookid))
    return -1;

  if (objectp(consumer)) {
    consumer = symbol_function("HookCallback", consumer);
    if (!closurep(consumer))
      return -2;
  }

  if (timeInSeconds > 0) {
      regtime=time() + timeInSeconds;
  }
  else {
      regtime=__INT_MAX__;
  }

  H_DMSG(sprintf("HRegisterToHook hookid %d consumer %O\n hookprio %d "
        "consumertype %d\n",hookid,consumer,hookprio,consumertype));

  CleanHookMapping(({hookid})); // entfernt ungueltige/abgelaufene Eintraege

  // nur einmal pro closure registrieren!
  if (HIsHookConsumer(hookid, consumer))
    return -3;

  // Consumertyp erlaubt?
  if (H_CONSUMERCHECK(consumertype) == -1
      || !HConsumerTypeIsAllowed(consumertype,GET_OBJECT(consumer)))
    return -4;

  // Prioritaet erlaubt?
  if (H_HOOK_VALIDPRIO(hookprio) == -1
      || !HPriorityIsAllowed(hookprio, GET_OBJECT(consumer)))
    return -5;

  struct hook_s hook = hookMapping[hookid];

  // Und surveyors erlauben die Registierung?
  if (!askSurveyorsForRegistrationAllowance(hook->surveyors,
                    GET_OBJECT(consumer),hookid,
                    hookprio,consumertype))
    return -6;

  string ctypename = H_CONSUMERNAMES[consumertype];

  // get the consumer array
  struct hook_entry_s *consumers = hook->(ctypename);

  // assemble new hook consumer struct
  struct hook_entry_s newconsumer = (<hook_entry_s>
                      cl : consumer,
                      prio : hookprio,
                      endtime : regtime,
                      type : consumertype );

  // consumers enthaelt die Hookeintraege
  if (sizeof(consumers) < MAX_HOOK_COUNTS[consumertype]) {
    // max. Anzahl an Eintraegen fuer diesen Typ noch nicht
    // erreicht, direkt anhaengen.
    consumers += ({ newconsumer });
    hook->(ctypename) = consumers;
    ret=1;
  }
  else {
    // gibt es einen Eintrag mit hoeherem Priowert (niedrigere
    // Prioritaet), den man ersetzen koennte?
    // Das Array ist sortiert, mit hoechsten Priowerten am
    // Ende. Ersetzt werden soll der Eintrag mit dem hoechsten
    // Zahlenwert, falls der neue Eintrag einen niedrigeren Wert
    // hat, d.h. es muss nur er letzte Consumer im Array geprueft werden.
    // Pruefung auf Closureexistenz, falls der Surveyor Objekte
    // zerstoert (hat)...
    struct hook_entry_s oh = consumers[<1];
    if (!oh->cl || oh->prio > newconsumer->prio) {
      // Found superseedable entry - replace it, but inform the object.
      H_DMSG("Found superseedable entry\n");
      consumers[<1] = newconsumer;
      GET_OBJECT(oh->cl)->superseededHook(hookid, this_object());
      ret = 1;
      // nicht noetig, consumers wieder in sein hook_s zu haenngen wegen Array
      // -> Referenz
    }
  }

  // wenn ein Eintrag hinzugefuegt wurde, muss neu sortiert werden
  if (ret) {
    hook->(ctypename) = sort_array(consumers,
        function int (struct hook_entry_s a, struct hook_entry_s b) {
            return a->prio > b->prio; } );
  }

  H_DMSG(sprintf("  result %O\n",hookMapping));

  // -7, wenn kein Eintrag mehr frei / zuviele Hooks
  return (ret > 0 ? 1 : -7);
}

// Conveniences wrapper for simple listener hooks
int HRegisterListener(int hookid, mixed consumer)
{
  return HRegisterToHook(hookid, consumer, H_HOOK_OTHERPRIO(2), H_LISTENER, 0);
}

// Cnveniences wrapper for simple modificator hooks
int HRegisterModifier(int hookid, mixed consumer)
{
  return HRegisterToHook(hookid, consumer, H_HOOK_OTHERPRIO(2),
                         H_HOOK_MODIFICATOR, 0);
}

// surveyors are asked for cancellation permittance
protected int askSurveyorsForCancelAllowance(mixed surveyors,
  object modifiyingOb,mixed data,int hookid,int prio,object hookOb){

  foreach(struct hook_entry_s surveyor : surveyors) {
    if (closurep(surveyor->cl) && surveyor->endtime >= time())
    {
      // surveyor hook gueltig.
      object sob = GET_OBJECT(surveyor->cl);
      if (!sob->HookCancelAllowanceCallback(modifiyingOb, hookid,
                        hookOb, prio, data))
        return 0;
    }
  }
  return 1;
}

// surveyors are asked for data change permittance
protected int askSurveyorsForModificationAllowance(mixed surveyors,
  object modifiyingOb,mixed data,int hookid,int prio,object hookOb){

  foreach(struct hook_entry_s surveyor : surveyors) {
    if (closurep(surveyor->cl) && surveyor->endtime >= time())
    {
      // surveyor hook gueltig.
      object sob = GET_OBJECT(surveyor->cl);
      if (!sob->HookModificationAllowanceCallback(modifiyingOb,
                        hookid, hookOb, prio, data))
        return 0;
    }
  }
  return 1;
}

protected mixed HookFlow(int hookid, mixed hookdata){
  mixed tmp, ret;

  ret=({H_NO_MOD,hookdata});

  H_DMSG(sprintf("HookFlow hookid %d hookdata %O\n",hookid,hookdata));

  if (!member(hookMapping, hookid))
    return ret;

  struct hook_s hook = hookMapping[hookid];

  // notify surveyors
  foreach(struct hook_entry_s h : hook->surveyors) {
    if (closurep(h->cl) && h->endtime >= time())
    {
      // Hook gueltig
      tmp = funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
      if(tmp[H_RETCODE]==H_CANCELLED) {
        ret[H_RETCODE]=H_CANCELLED;
        return ret;  // und weg...
      }
      else if(tmp[H_RETCODE]==H_ALTERED){
        ret[H_RETCODE]=H_ALTERED;
        ret[H_RETDATA]=tmp[H_RETDATA];
      }
    }
    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
    else if (find_call_out(#'CleanHookMapping) == -1) {
      call_out(#'CleanHookMapping, 0, ({hookid}));
    }
  } // surveyors fertig

  // notify hmods
  foreach(struct hook_entry_s h : hook->hmods) {
    if (closurep(h->cl) && h->endtime >= time())
    {
      // Hook gueltig
      tmp = funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
      if(tmp[H_RETCODE]==H_CANCELLED) {
        // ask allowance in surveyors
        if(h->cl &&
           askSurveyorsForCancelAllowance(hook->surveyors,
              GET_OBJECT(h->cl), hookdata, hookid,
              h->prio, this_object()))
        {
            ret[H_RETCODE] = H_CANCELLED;
            return ret; // und raus...
        }
      }
      else if(tmp[H_RETCODE]==H_ALTERED) {
        // ask allowance in surveyors
        if(h->cl &&
           askSurveyorsForModificationAllowance(hook->surveyors,
              GET_OBJECT(h->cl),hookdata, hookid,
              h->prio,this_object()))
        {
            ret[H_RETCODE] = H_ALTERED;
            ret[H_RETDATA] = tmp[H_RETDATA];
        }
      }
    }
    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
    else if (find_call_out(#'CleanHookMapping) == -1) {
      call_out(#'CleanHookMapping, 0, ({hookid}));
    }
  } // hmods fertig

  // notify dmods
  foreach(struct hook_entry_s h : hook->dmods) {
    if (closurep(h->cl) && h->endtime >= time())
    {
      // Hook gueltig
      tmp = funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
      if(tmp[H_RETCODE]==H_ALTERED) {
        // ask allowance in surveyors
        if (h->cl &&
            askSurveyorsForModificationAllowance(hook->surveyors,
              GET_OBJECT(h->cl),hookdata, hookid,
              h->prio,this_object()))
        {
            ret[H_RETCODE] = H_ALTERED;
            ret[H_RETDATA] = tmp[H_RETDATA];
        }
      }
    }
    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
    else if (find_call_out(#'CleanHookMapping) == -1) {
      call_out(#'CleanHookMapping, 0, ({hookid}));
    }
  } // dmods fertig

  // notify listener
  foreach(struct hook_entry_s h : hook->listeners) {
    if (closurep(h->cl) && h->endtime >= time())
    {
      // Hook gueltig
      funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
    }
    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
    else if (find_call_out(#'CleanHookMapping) == -1) {
      call_out(#'CleanHookMapping, 0, ({hookid}));
    }
  } // listener fertig

  return ret;
}

