// MorgenGrauen MUDlib
//
// upd.c
//
// $Id: upd.c 8850 2014-06-13 21:34:44Z Zesstra $
#pragma strict_types
#pragma save_types
#pragma range_check
#pragma no_clone

#define NEED_PROTOTYPES
#include <magier.h>
#include <player.h>
#undef NEED_PROTOTYPES
#include <debug_info.h>
#include <wizlevels.h>
#include <moving.h>
#include <properties.h>
#include <logging.h>
#include <thing/properties.h>

varargs static int _make(string file, int flags, int recursive);

static mixed _query_localcmds()
{
  return ({({"upd","_upd",0,LEARNER_LVL}),
           ({"load","_load",0,LEARNER_LVL})});
}

//
// _save(): Spieler in Rettungsraum retten
// obj:      Spielerobjekt(?)
// inv_save: Rettungsraumname 
// Rueckgabe: 0 wenn kein Spielerobjekt
//            Spielerobjekt, falls doch
//

static mixed _save( object obj, object inv_saver )
{ 
    if ( query_once_interactive(obj) )
      { 
        obj->move( inv_saver, NO_CHECK );
        return obj;
      }
    return 0;
}


//
// _reload(): Objekt laden
// file:  Filename. Muss in der Form /xx/xx/xx.c vorliegen
// clone:  > 0 -> Es soll geclont werden, enthaelt Objektnummer des
//                Vorgaengerobjektes
// flags: Kommandozeilenoptionen
// err:   Leerstring als Referenz uebergeben. Enthaelt nach dem
//        Aufruf vom _reload() die Fehlermeldungen als String.
// Rueckgabe: Das neu erzeugte Objekt bzw. das schon vorhandene Objekt
//            bzw. 0, wenn Fehler auftrat.
//

private object _reload(string file, int clone, int flags, string err)
{
  object obj;
  
  if (!obj=find_object(file[0..<3]+(clone?("#"+clone):"")))
  {
    int pos,pos2;
    string bt;

    if(file_size(file)<0)
    {
      if (file_size(file)==-1)
        err = sprintf("upd: %s: Datei existiert nicht.\n", file);
      else // directory
        err = sprintf("upd: %s: Verzeichnisse koennen nicht geladen "
                      "werden.\n",file);
      return obj; // 0
    }
    pos = max(file_size(__DEBUG_LOG__),0);

    if ((err = (clone?catch(obj = clone_object(file)):
                catch(load_object(file)) )) && (flags & UPD_B))        
    {     
      if (( pos2=file_size(__DEBUG_LOG__)) > pos )
        err+=sprintf("\nBacktrace:\n%s",
                     read_bytes(__DEBUG_LOG__,pos, pos2-pos ));
      else
        err+=sprintf("\nKEIN BACKTRACE VERFUEGBAR!\n");
    }
    if (!err&&!obj&&(!obj = find_object(file[0..<3])))
      err += sprintf( "upd: %s: Blueprint nach dem Laden zerstoert.\n",file );
  }
  else
    err=sprintf("upd: Objekt existiert schon: %O\n",obj);
  return obj;
}


//
// _update(): File updaten -> Blueprint destructen
// file:  Filename
// dummy: simulieren? (1->wird nicht aktualisiert)
// flags: Kommandozeilenoptionen
// Rueckgabe: -1: Keine Vollzugriff
//             0: Objekt ist nicht geladen
//             1: Operation wird durchgefuehrt
//

private varargs int _update(string file, int dummy, int flags)
{
  object obj;
  string err;
  if (!dummy && !objectp(obj = find_object(file))) return 0;
  if (!IS_ARCH(this_object()))
  {
    // Schreibrechte nur pruefen, wenn echt aktualisiert werden soll.
    if(!dummy && !MAY_WRITE(file))
      return (printf("upd: %s: Keine Schreibrechte!\n",file), -1);
    if(!MAY_READ(file))
      return (printf("upd: %s: Keine Leserechte!\n", file), -1);
  }
  if (dummy) return 1;
  
  if ( flags & UPD_D )
  {
    object *inv;
    if (sizeof(inv = deep_inventory(obj)))
    {
      printf("upd: %s: Entferne Objekte im Inventar\n", file );
      if (!(flags&UPD_H))
      {
        if(err=catch(filter_objects( inv, "remove", 1 )))
          printf("upd: %s: Fehlgeschlagen. Grund:\n%s\n",
                 file,err);
      }
      if (sizeof(inv = deep_inventory(obj)))
        filter(inv, function void (object ob)
            {destruct(ob);});
    }
  }
  if (!(flags&UPD_H))
  {
    if(err = catch(obj->remove()))
      printf("upd: %s: remove() fehlgeschlagen. Aufruf von " +
             "destruct().\n",file);
  }
  if(objectp(obj)) destruct(obj);
  return 1;
}


//
// _instance_upd(): Alle Objekte nach Clones des Objekts durchsuchen
// file:  Filename des Objektes
// flags: Kommandozeilenargumente
// obj:   Aktuelles Objekt
// instances: Zahl der gefundenen Instanzen
//

private void _instance_upd(string file, int flags, mixed obj, int instances,
                           int firstcall)
{
 int i;
 if (firstcall)
    printf("upd: %s: %s Instanzen.\n",file,flags&UPD_A?"Aktualisiere":"Suche");
  
  while (get_eval_cost()>220000 && i < sizeof(obj))
  {
    if (!objectp(obj[i]))
      instances--;
    else
    {
      if (flags&UPD_F&&!(flags&UPD_S))
        printf( "upd: %O gefunden in %s\n", obj[i],
                environment(obj[i])?object_name(environment(obj[i])) 
                : "keiner Umgebung" );
      if (flags&UPD_A) _make(object_name(obj[i]), flags & ~(UPD_A|UPD_F),1 );
    }
    i++;
  }
  if (i < sizeof(obj)) 
    call_out( #'_instance_upd/*'*/,2,file,flags,obj[i..],instances,0);
  else
    printf( "upd: %s: %d Instanzen %s\n", file, instances,
            (flags & UPD_A) ? "aktualisiert" : "gefunden" );
  return;
}
  
  
//
// _do_make(): Alle geerbten Objekte bearbeiten (fuer -m/-v)
// file:  Name des Files
// clone: 0, wenn blueprint, ansonsten Clonenummer
// flags: Kommandozeilenparameter
// dep:   geschachteltes Array mit Meldungen (wg. Rekursion)
// ready: Array der schon bearbeiteten Objekte (wg. Rekursion)
// Rueckgabe: Array der Objektnamen, die bearbeitet wurden
//            (Array in Array in ...)
// 

varargs private int _do_make( string file,int clone,int flags,mixed dep,
                              string *ready )
{
  object obj;
  string err;
  string *ilist;
  mixed downdeps;
  int ret;
  
  if (!pointerp(ready)) ready = ({});
  ready += ({ file });
  
  if ( !(obj = _reload(file,clone,flags,&err)))
  {
    dep += ({ err });
    return 0;
  }
  
  ilist = inherit_list(obj)-ready;
  
  downdeps = ({});
  
  while (sizeof(ilist))
  {
    ret = _do_make( ilist[0],0,flags, &downdeps, &ready )||ret;
    ilist[0..0] = ({});
    ilist -= ready;
  }
  
  if ( ret||file_time(file)>program_time(obj)||(flags &UPD_I))
    if ( _make( file, flags & ~(UPD_M|UPD_I) ,1) < 0 ) 
      dep = ({ "{" + explode(file,"/")[<1] + "}", downdeps });
    else{
      dep = ({ "[" + explode(file,"/")[<1] + "]", downdeps });
      ret = 1;
    }
  else if (flags&UPD_V) dep += ({ explode(file,"/")[<1], downdeps });
  return ret;
}


//
// _make_dep(): Ausgabe des Ererbungsbaumes
// Objekte im Array dep
// prefix enthaelt Zeilenanfang (fuer Rekursion)
// Rueckgabe: String mit dem Vererbungsbaum des Objektes
//

private string _make_dep( mixed dep, string prefix )
{
  string ret;
  int i, size;
  
  ret="";
  size=sizeof(dep);
  for (i=0; i<size;i++)
    if (pointerp(dep[i]))
      ret += _make_dep(dep[i],prefix + (i < (size-1) ? "| ":" "));
    else 
      ret += prefix + "+-" + dep[i] + "\n";
  return ret;
}


//
// _illegal_closure(): ist closure in arg an objekt gebunden?
// arg: closure(-array/mapping)
// Rueckgabe: 0 wenn alles okay
//            1 wenn closure geloescht werden muss
//

private int _illegal_closure( mixed arg )
{
  int i, j;
  string *indices;
  
  if ( closurep(arg) && !objectp(query_closure_object(arg)) )
    return 1;
  
  if ( pointerp(arg) ){
    for ( i = sizeof(arg); i--; )
      if ( _illegal_closure(arg[i]) )
        return 1;
  }
  else if ( mappingp(arg) ){
    indices = m_indices(arg);
    for ( i = sizeof(indices); i--; )
      for ( j = get_type_info( arg, 1 ); j--; )
        if ( _illegal_closure(arg[indices[i], j]) )
          return 1;
  }
  return 0;
}

//
// _make(): Update file
// file:  Filename
// flags: Kommandozeilenargumente
//

varargs static int _make(string file, int flags,int recursive)
{
  string msg, err, blue;
  int inst;
  object obj, inv_saver;
  mixed tmp;
  
  msg = "";

  if (!file) return printf( "upd: Kein Filename uebergeben!\n" ), RET_FAIL;
    
// Filename in Blue, Objektname in blue, Instanznummer in inst

  if (sscanf(file,"%s#%d",blue,inst)==2) blue += ".c";
  else blue = file + (file[<2..]==".c" ? "" : ".c");

// Alle Instanzen durchsuchen im Falle von -a oder -f 

  if ((flags & UPD_LOAD)&&find_object(file))
    return printf("load: %s: Objekt ist schon geladen.\n",file),RET_OK;
  
  if ( flags & (UPD_F|UPD_A))
  {
    if (inst) return printf( "upd: %s: Eine Instanz kann keine " +
                             "Clones haben.\n",file ), RET_FAIL;
    if ((tmp=_update(file, 1,flags))==-1) 
      return printf( "upd: %s: Kein Vollzugriff auf die " +
                     "Datei erlaubt.\n",file), RET_FAIL;
    if (tmp==0) return RET_FAIL;

   tmp=clones(blue[0..<3],2);
    if (sizeof(tmp))
      call_out( #'_instance_upd/*'*/, 0, file,flags,tmp,sizeof(tmp),1);
    else
      printf( "upd: %s: Keine Clones vorhanden!\n", blue[0..<3]);

    if ( (flags & UPD_F) && !(flags &(UPD_R|UPD_L|UPD_LOAD))) return RET_OK; 
    // Nichts laden -> Auch kein Backup
  }

// Backupraum festlegen
   
  if( blue==INV_SAVE ) {
                printf("upd: Achtung: Raum zum Zwischenspeichern soll geladen werden?!\n");
        } 
  if ( !(inv_saver=load_object(INV_SAVE)) )
  {
    printf("upd: %s: Raum zum Zwischenspeichern des " +
           "Rauminhalts ist nicht ladbar.\n" +
           "         %s\n",file,INV_SAVE);
    return RET_FAIL;
  }

// Wenn das Objekt existiert bzw. Deep aktualisiert werden soll

  if ( (!(flags&UPD_LOAD))&&
       ((obj = find_object(file)) || (flags & (UPD_M|UPD_I))))
  {
    object *inv, env, *pl_inv;
    mapping pro;
    int i;
    mixed configdata;
    int restore_config;

    // Wenn Objekt existiert, dann Inhalt und ggf. Daten aus Configure() oder
    // Props sichern:
    if (obj)
    {
      // im Fall UPD_C erfolgt _kein_ Auslesen und _keine_ Restauration
      // mittels Configure()
      if ( ! (flags & UPD_C ) )
      {
        catch(restore_config=call_resolved(&configdata,obj,
                                                  "Configure",0);
              publish);
        // Wenn UPD_CONF gesetzt wird, _muss_ das Objekt ein oeffentliches
        // Configure() definieren, sonst erfolgt Abbruch.
        if ((flags & UPD_CONF) && !restore_config)
        {
          printf("upd: %s: hat kein Configure(), Zerstoerung abgebrochen.\n",file);
          return RET_FAIL;
        }
      }
      if (!(flags&UPD_D)&&(flags&(UPD_L|UPD_R)))
      {
        if (i=sizeof(inv=(all_inventory(obj)-({0}))))
        {
          mixed items;
          // Herausbekommen, ob hier Items existieren, die per AddItem 
          // erzeugt werden. Die duerfen nicht gesichert werden.
          items=({mixed})obj->QueryProp(P_ITEMS); // mixed, da array of arrays
          if (pointerp(items)&&sizeof(items))
          {
            items=transpose_array(items)[0];
            while (i--)
              if (member(items, inv[i])==-1)
                    inv[i]->move(inv_saver,NO_CHECK);
          }
          else // In diesem Objekt sind keine Items gesetzt.
            while (i--) inv[i]->move(inv_saver,NO_CHECK);
        }
      }
      else
      {
        inv=map( deep_inventory(obj), #'_save/*'*/, inv_saver )-({0});
      }
      env = environment(obj);
      if ( flags & UPD_C )
      {
        pro = ({mapping})(obj->QueryProperties());
      }
    }
    else inv = ({});

// Ererbte Objekte durchsuchen.
    if ( flags & (UPD_M|UPD_I) )
    {
      mixed dep;
      dep = ({});
      _do_make( blue, inst, flags & ~(UPD_M|UPD_L|UPD_R|UPD_F|UPD_A), &dep );
      printf( _make_dep( dep, "" ) + "\n" );
    }
   
// Tatsaechlichen Update durchfuehren
   
    if ( _update(file, 0, flags)< 0) return RET_FAIL;
    msg += (inst ? "zerstoert" : "aktualisiert");
    
// Neu laden ??
    if ( flags & (UPD_R|UPD_L) )
    {
      if ( obj = _reload( blue,inst,flags, &err ) )
        msg += ", " + (inst ? "neu geclont" : "neu geladen");
     
// Neu geladen: Properties wiederherstellen, Closures filtern 
      if (!err)
      {
        if (!obj) obj = find_object(file);
        // Wenn gewuenscht, Props zurueckschreiben (hat Prioritaet vor
        // Configure(), weil explizit vom Magier angefordert).
        if ( pro && (flags & UPD_C) )
        {
          string *names;
          
          names = m_indices(pro);
          
          // Closures in (mittlerweile) zerstoerten Objekten
          // rausfiltern, damit die (hoffentlich korrekten) Closures
          // im neu geclonten Objekt erhalten bleiben
          for ( i = sizeof(names); i--; )
            if ( _illegal_closure(pro[names[i], F_VALUE]) ||
                 _illegal_closure(pro[names[i], F_QUERY_METHOD]) ||
                 _illegal_closure(pro[names[i], F_SET_METHOD]) )
              m_delete( pro, names[i] );
          
          obj->SetProperties(pro);
          msg += ", Properties gesetzt";
        }
        // Wenn kein UPD_C, wird ggf. das Ergebnis von Configure() wieder
        // uebergeben.
        else if (restore_config)
        {
          int conf_res;
          if (!catch(conf_res=({int})obj->Configure(configdata); publish)
              && conf_res == 1)
          {
            msg += ", (re-)konfiguriert";
          }
          else
          {
            msg += ", (Re-)Konfiguration fehlgeschlagen";
            if (flags & UPD_CONF)
              printf("upd: Daten von %s konnten nicht rekonfiguriert werden: "
                           "%O\n", file, configdata);
          }
        }
        if (env)
        {
          if ( obj->move( env, NO_CHECK ) <= 0 )
            printf( "upd: /%O konnte nicht in /%O zurueckbewegt werden\n",
                    obj, env );
          else
            msg += ", bewegt";
        }
        if (i=sizeof(inv))
        {
          while(i--) if (inv[i]) inv[i]->move(obj, NO_CHECK );
          msg += ", Inhalt zurueckbewegt";
        }
      }
      else 
        return printf( "upd: %s: %s", file, err ), RET_FAIL;
    }
  }
  else 
    if ( !_update(file, 0, flags) && (flags & (UPD_L|UPD_LOAD)) )
      if ( !_reload( blue, inst, flags, &err ) )
        return printf( "%s: %s: %s", (flags&UPD_LOAD?"load":"upd"),file, err ),
          RET_FAIL;
      else
        msg += "geladen";
  
  if ( sizeof(msg)&&!(flags&UPD_S&&recursive) )
    printf("%s: %s: %s.\n",(flags&UPD_LOAD?"load":"upd"),file,msg);
  return RET_OK;
}

//
// _upd: Objekte laden, zerstoeren und aktualisieren
//

static int _upd(string cmdline)
{
  int flags;
  mixed *args;

  cmdline=_unparsed_args();
  args=parseargs(cmdline,&flags,UPD_OPTS,1);
  if(flags==-1||!sizeof(args))
    return USAGE("upd [-"+UPD_OPTS+"] <datei> [<datei> ..]");
  if ((flags & UPD_C) && (flags & UPD_CONF))
  {
    printf("upd: -c und -C gleichzeitig werden nicht unterstuetzt.\n");
    return 1;
  }
  args=file_list(args,MODE_UPD,0,"/");
  if(!sizeof(args)) return printf("upd: Keine passende Datei gefunden!\n"),1;

  args=map(args,(: $1[FULLNAME] :))-({0});

  if(!sizeof(args))
  {
    printf("upd: Verzeichnisse koennen nicht aktualisiert werden!\n");
    return 1;
  }
  asynchron(args,#'_make,flags,0,0);
  return 1;
}

//
// _load: Objekte laden
//

static int _load(string cmdline)
{
  int flags;
  mixed *args;

  cmdline=_unparsed_args();
  args=parseargs(cmdline,&flags,"",1);
  if(flags==-1||!sizeof(args))
    return USAGE("load <datei> [<datei> ..]");
  args=file_list(args,MODE_UPD,0,"/");
  if(!sizeof(args)) return printf("load: Keine passende Datei gefunden!\n"),1;
  args=map(args,(: (($1[FILESIZE]!=-2||find_object($1[FULLNAME]))?
                          $1[FULLNAME]:0) :))-({0});

  if(!sizeof(args))
    return printf("load: Verzeichnisse koennen nicht geladen werden!\n"),1;
  asynchron(args,#'_make,UPD_LOAD,0,0);
  return 1;
}
