// 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
#pragma pedantic

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