// 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=(mixed)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;
}
