// MorgenGrauen MUDlib
//
// thing/properties.c -- most general class (property handling)
//
// $Id: properties.c 6951 2008-08-09 23:08:31Z Zesstra $

// Properties.c -- Propertyverwaltung
// (c) 1993 Hate@MorgenGrauen, Mateese@NightFall
//          Idea and Code      Flames and Destructions
// -> *grin* thats the point actually :) 
//
// Ueberarbeitet von Jof       am 12.06.1994
// Ueberarbeitet von Mandragon am 11.05.2003

#pragma strict_types
#pragma save_types
#pragma range_check
#pragma no_clone

#include <driver_info.h>

#define NEED_PROTOTYPES

#include "/sys/thing/properties.h"
#include "/secure/wizlevels.h"

// the mapping where the actual properties are stored. Direct initialization.
// Indexed with F_VALUE, F_MODE, F_SET_METHOD, F_QUERY_METHOD, F_VALIDATOR
// F_MODE, F_SET_METHOD, F_QUERY_METHOD and F_VALIDATOR are usually 'sparse'
// (i.e. there is no entry for most properties), therefore it is more
// memory-efficient to store them like this than in one mapping, although it
// requires more mapping lookups.
private nosave mapping *prop = allocate(F_PROP_ENTRIES, ([]));

// the mapping that is used for saving. During save_object/restore_object it
// contains the properties with SAVE flag. 
// This is empty outside of a save_object() or restore_object() call!
private mapping properties;


// Z.Zt. nur Abschalten des Resets noetig.
protected void create() {
  // Blueprints in /std benoetigenkeinen Reset ....
  if (object_name()=="/std/thing/properties")
    set_next_reset(-1);
}

protected void create_super() {
  set_next_reset(-1);
}

// Prueft, ob ein Zugriff auf eine Property erlaubt ist.
// Properties, die SECURED oder PROTECTED sind, duerfen nur vom Objekt
// selber, EM+ oder ROOT veraendert werden.
#define SAVE_OBJECT      1
#define PROP_SET         2
#define PROTECTED_SET    3
#define PROTECTED_DELETE 4
#define SECURED_SET      5
#define SECURED_DELETE   6
nomask private int prop_check_privilege(int drop_priv, int mode,
          int op=PROP_SET)
{
  // Interne Calls oder eigenes Objekt (als letzter 'externer' Aufrufer via
  // Callother) darf alles
  if (!drop_priv || previous_object() == this_object())

    return 1;

  // Ab hier nur noch fremde Objekte
  switch(op)
  {
    case SAVE_OBJECT:
      // Eigentlich nur vom jeweils aktiven simul_efun-Objekt gerufen, aber
      // der einfacheit halber sind alle ROOT-Objekte erlaubt. Aber nur
      // direkten Caller pruefen, *nicht* ROOT_SECURITY!
      if (get_euid(previous_object()) == ROOTID)
        return 1;

    case SECURED_DELETE:
      // Das SECURED-Flag darf bei Properties nicht mehr geloescht werden
      return 0;

    case SECURED_SET:
      if (geteuid(previous_object()) == ROOTID || ARCH_SECURITY)
        return 1;

    case PROTECTED_DELETE:
    case PROTECTED_SET:
    case PROP_SET:
      // Properties, die schon SECURED oder PROTECTED sind, duerfen
      // nur vom Objekt selber manipuliert werden
      if (!(mode & (PROTECTED|SECURED)) // nicht geschuetzt
          || (geteuid(previous_object()) == ROOTID || ARCH_SECURITY))
        return 1;
  }
  return 0;
}

// Set() -- provides direct access to a property, no filters
// Type=F_VALUE und drop_priv=extern_call() by default
public mixed Set(string name, mixed Value, int Type, int drop_priv)
{
  int mode = prop[F_MODE][name];
  // Es ist verfuehrerisch, das 'drop_priv||extern_call()' durch 'drop_priv' zu
  // ersetzen, weil extern_call() das default-argument fuer <drop_priv> ist.
  // Das ist keine gute Idee, weil <drop_priv> unter der Kontrolle des Aufrufers
  // ist und dieser 0 uebergeben kann. Sprich: wenn es 0 ist, muessen wir
  // dennoch selber pruefen. Wir glauben aber immer, wenn es 1 ist, der
  // Aufrufer hat nichts davon und das eigene Objekt darf Privilegien abgeben.
  drop_priv = drop_priv||extern_call();

  // Erstmal pruefen, ob Aenderung der Prop erlaubt ist.
  if (!prop_check_privilege(drop_priv, mode, PROP_SET))
    return -1;
  // Bemerkung: aktuell koennen alle Objekte PROTECTED setzen. Loeschen
  // koennen es ROOT, EM+ und ME ueber den Check oben.

  // Soll SECURED geloescht werden und ist das erlaubt?
  if ((Type==F_MODE||Type==F_MODE_AD) && (Value & SECURED)
      && !prop_check_privilege(drop_priv, mode, SECURED_DELETE))
    return -2;

  // Soll SECURED gesetzt werden und ist das erlaubt?
  if ((Type==F_MODE||Type==F_MODE_AS) && (Value&SECURED)
      && !prop_check_privilege(drop_priv, mode, SECURED_SET) )
    return -3;

  switch(Type)
  {
    // Je nach Modus Flags veraendern
    case F_MODE_AS:  prop[F_MODE][name]|= Value;
                     return prop[F_MODE][name];
    case F_MODE_AD:  prop[F_MODE][name]&= ~Value;
                     if (!prop[F_MODE][name]) prop[F_MODE]-=([name]);
                     return prop[F_MODE][name];
    case F_MODE:     prop[F_MODE][name]^= Value;
                     if (!prop[F_MODE][name]) prop[F_MODE]-=([name]);
                     return prop[F_MODE][name];

    // Query- und Setmethoden laufen ab hier durch.
    case F_SET_METHOD:
    case F_SET_MAPPER:
      // SETMAPPED passend setzen
      if (Type==F_SET_METHOD)
        prop[F_MODE][name] &= ~SETMAPPED;
      else
        prop[F_MODE][name] |= SETMAPPED;
      // Ab hier alles gleich
      // -1 als Setz-Methode: Nosetmethod setzen
      if (Value == -1)
      {
        prop[F_SET_METHOD]-=([name]);
        prop[F_MODE][name] |= NOSETMETHOD;
        return 0;
      }
      // Kein break! Rest wie Querymethod
    case F_QUERY_METHOD:
      // Ungebundene Lambda_Closure? Heutzutage ein Fehler.
      if (closurep(Value) && !query_closure_object(Value))
      {
        raise_error("Ungebundene Lambdas sind als Querymethoden "
                    "nicht mehr unterstuetzt.\n");
      }
      // Kein break!
    default:
      if (!Value) prop[Type]-=([name]);
      else prop[Type][name] = Value;
  }

  // Gesamtwert zurueckgeben
  return prop[Type][name];
}


// Direktes Auslesen der Property ohne Filter ...
// Type = F_VALUE by default
public mixed Query( string name, int Type )
{
    if (pointerp(prop)) return prop[Type][name];
    return 0;
}

// Property setzen unter Verwendung evtl. vorhandener Zugriffsfunktionen
public mixed SetProp( string name, mixed Value, int drop_priv)
{
  mixed result;

  int mode = prop[F_MODE][name];
  // NOSETMETHOD: Darf nicht gesetzt werden
  if (mode & NOSETMETHOD ) return -1;

  // Set-Method abfragen, so vorhanden
  // TODO: nachdem alle moeglichen Werte als Set-Methode illegal sind, auf
  // closure aendern.
  mixed func = prop[F_SET_METHOD][name];
  if (func)
  {
    // Wert als Set-Method? gleich zurueckgeben
    if (!closurep(func)) return func;

    // An dieser Stelle muss func eine Closure sein. Da Set() ungebundene
    // Lambdas bindet, kann es auch nur eine gebundene Closure sein und das
    // Objekt existiert auch noch (sonst waere func == 0).

    // Dann mal die Closure aufrufen. Bei Fehler selbige loeschen
    if (catch(result=funcall(func, Value, name);publish))
    {
      prop[F_SET_METHOD]-=([name]);
    }
    else // Erfolgreicher call
    {
      if (mode & SETMAPPED) // SM hat noch nicht selber gesetzt
        result = Set( name, result, F_VALUE, drop_priv||extern_call() );
    }

    // Und zurueckgeben
    return result;
  }

  // _set_*-Methode vorhanden? falls ja, aufrufen.
  if (call_resolved(&result,this_object(),"_set_"+name,Value ))
        return result;

  // Letzte Moeglichkeit: Muss eine 'normale' Property sein
  // Es ist verfuehrerisch, das 'drop_priv||extern_call()' durch 'drop_priv'
  // zu ersetzen, weil extern_call() das default-argument fuer <drop_priv>
  // ist. Das ist keine gute Idee, weil <drop_priv> unter der Kontrolle des
  // Aufrufers ist und dieser 0 uebergeben kann. Sprich: wenn es 0 ist,
  // muessen wir dennoch selber pruefen. Wir glauben aber immer, wenn es 1
  // ist und der Aufrufer Privilegien abgeben will.
  return Set( name, Value, F_VALUE, drop_priv||extern_call() );
}


// Property auslesen unter Verwendung evtl. vorhandener Zugriffsfunktionen
public mixed QueryProp( string name )
{
  mixed result;
  // Query-Methode vorhanden?
  mixed func = prop[F_QUERY_METHOD][name];
  if (func)
  {
    // Wert als Query-Method? Gleich zurueckgeben ...
    if (!closurep(func)) return func;
 
    // An dieser Stelle muss func eine Closure sein. Da Set() ungebundene
    // Lambdas bindet, kann es auch nur eine gebundene Closure sein und das
    // Objekt existiert auch noch (sonst waere func == 0).
   
    // Dann Mal die Closure aufrufen. Bei Fehler selbige loeschen
    if (catch(result=funcall(func, prop[F_VALUE][name]);publish))
    {
      prop[F_QUERY_METHOD]-=([name]);
    }
    
    // Und zurueckgeben
    return result;
  }
  // _query_*-Methode vorhanden? falls ja, aufrufen.
  else if (call_resolved(&result,this_object(),"_query_"+name))
    return result;

  // Hilft alles nichts. Es ist eine 'normale' Property ...
  return prop[F_VALUE][name];
}

// Addiert einen Wert zu einer Prop. Eigentlich ist es nur ein Short-Cut fuer
// QueryProp und += und SetProp. Dementsprechend gehen auch hier nur
// Typ-Kombinationen, die += auch kann.
public mixed AddToProp(string pname,
                       <int|float|string|mixed*|mapping|bytes> add_value)
{
  mixed value = QueryProp(pname);
  string err = catch(value += add_value; nolog);
  if (err)
    raise_error(sprintf("Nicht unterstuetzter Typ des Summanden: %s\n",
                        err[strstr(err,":")+2..]));

  return SetProp(pname, value, extern_call());
}

// "subtrahiert" einen Wert von einer Prop. Eigentlich ist es nur ein
// Short-Cut fuer QueryProp und -= und SetProp. Dementsprechend gehen auch
// hier nur Typ-Kombinationen, die -= auch kann.
public mixed SubFromProp(string pname,
                       <int|float|string|mixed*|mapping|bytes> sub_value)
{
  mixed value = QueryProp(pname);
  string err = catch(value -= sub_value; nolog);
  if (err)
    raise_error(sprintf("Nicht unterstuetzter Typ des Subtrahenden: %s\n",
                        err[strstr(err,":")+2..]));

  return SetProp(pname, value, extern_call());
}

// Viele Properties auf einen Schlag setzen.
// Wurde genutzt von simul_efun zum Setzen aller Properties, welche im
// restore_object() eingelesen wurden.
// Nutzer in Lib: Magiershell (upd), Spellbooks Zaubis, Klerus, Lupe
// Andere objekt-externe Nutzung ausdruecklich **NICHT** supportet!
// Problem: ggf. Verlust von SECURED, wenn Props kopiert werden (im alten
//   SECURED; im neuen nicht und nicht-privilegiertes Objekt
// Problem 2: beim Kopieren von einem alten in ein neues Objekt gehen alle
//   internen QM/SM auf das eigene Objekt ersatzlos kaputt.
// Problem 3: beim "Clonen" von Objekten haben beide Clones dann geteilte
//   Referenztypen wie Mappings/Structs/Arrays
public deprecated void SetProperties( mapping props )
{
  int i, j;

  // Kein Mapping? Schlecht ...
  if(!mappingp(props)) return;

  string *names = m_indices(props);

  // Das SECURED-Flag darf nur durch das Objekt selber gesetzt werden:
  // mode ist hier egal. Antwort cachen fuer den Loop
  int no_secure = !prop_check_privilege(extern_call(), 0, SECURED_SET);

  j=sizeof(names);
  while(j--)
  {
    if (prop_check_privilege(extern_call(), prop[F_MODE][names[j]],
                             PROP_SET))
    {
      // Prop-Setzen erlaubt, aber ggf. SECURED flag loeschen, wenn nicht
      // das nicht erlaubt ist (s.o.).
      if (no_secure)
        props[names[j], F_MODE] &= ~SECURED;
      // jetzt die einzelnen Teile der Prop seztzen.
      i=F_PROP_ENTRIES;
      while(i--)
      {
        if(props[names[j],i])
          prop[i][names[j]] = props[names[j], i];
        else
          prop[i]-=([names[j]]);
      }
    }
  }
}


// Ein Mapping mit allen Properties zurueckgeben
// Wurde genutzt von simul_efun im save_object() zur Abfrage aller Properties,
// um hieraus die gespeicherten zu bestimmen.
// Nutzer in Lib: Magiershell (upd), Spellbooks Zaubis, Klerus, Lupe,
// Listmaster-Zaubis, Fingerdaemon, Kaempfergilde (Karteikarten)
// Andere objekt-externe Nutzung ausdruecklich **NICHT** supportet!
// TODO fuer zukuenftige Features (wie private Properties) auf die simul_efun
// beschraenken.
// Problem: QueryProperties: die Werte entsprechen Query, nicht QueryProp und
// Abfragende werten die QMs in der Regel nicht aus (und waere auch nicht
// dieselbe Abfragesituation und wuerde daher nicht funktionieren).
// Problem 2: Herausgabe interner Daten wie Closures, Referenztypen wie
// Mappings/Arrays/Structs etc. Diese koennen dann geaendert werden oder im
// Falle von Closures sind ggf. private lfuns rufbar (stimmt: momentan koennen
// die auch per Query abgefragt werden).
public deprecated mapping QueryProperties()
{
  mapping props;
  int i, j;
  string *names;

  props = m_allocate( sizeof(prop[F_VALUE]), F_PROP_ENTRIES );

  if (pointerp(prop))
  {
    i=F_PROP_ENTRIES;
    while(i--)
    {
      names = m_indices(prop[i]);
      j=sizeof(names);
      while(j--) props[names[j], i] = prop[i][names[j]];
    }
  }
  return props;
}

// Die Properties als urspruengliches Array zurueckgeben, wird fuers MG-Tool
// benoetigt.
public mixed *__query_properties()
{
  if ( pointerp(prop) )
    return(deep_copy(prop));
  else
    return allocate(F_PROP_ENTRIES, ([]));
}


// Wird aus simul_efun (und nur von dort) gerufen, sollte die Properties aufs
// Speichern vorbereiten und alle *gespeicherten* Props in passender Form in
// der gespeicherten Variable <properties> ablegen.
public void _prop_prepare_save()
{
  // 2 Werte pro Prop (Wert + Modusflags) speichern
  // F_SET_METHOD, F_QUERY_METHOD werden nicht gespeichert.
  // Anzahl gespeicherter Props raten, 20% der Props mit Modusflags
  properties = m_allocate(sizeof(props[F_MODE])/5, 2);
  foreach(string pname, int mode: props[F_MODE])
  {
    if (mode & SAVE)
    {
      // Uralte, ungenutzte Flags loeschen sowie SETMAPPED (F_SET_METHOD wird
      // nicht gespeichert)
      properties[pname, F_MODE] = mode &
            (~(SETMNOTFOUND|QUERYMNOTFOUND|QUERYCACHED|SETCACHED|SETMAPPED));
      properties[pname, F_VALUE] = props[F_VALUE][pname];
    }
  }
}

// Wird nach dem Speichern gerufen und kann ggf. aufraeumen. Vor allem wird
// der Inhalt von <properties> geloescht, da dies nur beim Speichern relevant
// ist (und auch nicht gecached werden kann!).
public void _prop_finalize_save()
{
  properties = 0;
}

// Konvertiert die Daten in <properties> wieder in die Laufzeitform und mergt
// sie mit den bereits existierenden Props.
public void _prop_finalize_restore()
{
  // Da wir das eigene Savefile oder Savestring restaurieren, koennen wir
  // alle Rechte ignorieren. Wer das Savefile schreiben kann, hat gewonnen...
  // Und Savestrings muss das Objekt selber in seinen restore_object()-Aufruf
  // schreiben.
  foreach(string pname, mixed value, int mode: properties)
  {
    props[F_VALUE][pname] = value;
    // mode aus dem Savefile wird uebernommen, ausser SETMAPPED, was vom
    // bisher gueltigem mode uebernommen werden muss.
    if (props[F_MODE][pname] & SETMAPPED)
      mode &= SETMAPPED;
    props[F_MODE][pname] = mode;
    // F_SET_METHOD und F_QUERY_METHOD werden beibehalten, sollten sie vor dem
    // restore bereits gesetzt sein. Aus dem Savefile kommen beide nie.
  }
  properties = 0;
}
