// 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 int 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.
// returns the number of valid consumers left.
protected int CleanHookMapping(int *hookids)
{
  // hooks enthaelt die aufzuraeumenden Hooks. Wenn kein Array -> alle Hooks
  if (!pointerp(hookids))
    hookids=m_indices(hookMapping);

  int count;
  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 und die anderen/gueltigen zaehlen.
        if (!h->cl || h->endtime < time() )
            h = 0;
        else
            ++count;
      }
      // 0 noch rauswerfen.
      hooks->(consumertype) -= ({0});
    }
  }
  return count;
}

// Returns the number of valid consumers for the given hooks (or all, if
// hooks==0).
// Side effect: Cleans the internal structures and removes any stale
// consumers.
public varargs int HHasConsumers(int *hookids)
{
  return CleanHookMapping(hookids);
}

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;
}

