/*
 * Mudlibseite des iplookup systems, mit dem aus numerischen IP Adressen
 * der Hostname und der Ort, an dem sich der Rechner befinden berechnet wird.
 * Ergebnisse werden gecachet.
 *
 * (c)2010 rumata @ morgengrauen
 */

#pragma strict_types,save_types
#pragma no_clone,no_shadow

// Format der ipmap:
// Key: numerische ip als string (ohne fuehrende nullen)
// Data:
//  [ip,0] Hostname, der vom externen Server geliefert wurde.
//  [ip,1] Locationinformation, die vom externen Server kommt.
//    dieser sollte den Ort, oder falls es nicht besser geht, das Land
//    im Klartext liefern.
//  [ip,2] Zeitstempel, bei dessen erreichen der Wert geloescht werden
//    soll.
//  [ip,3] Status der Anfrage

private mapping ipmap;
#define IPMAP_HOST   0
#define IPMAP_CITY   1
#define IPMAP_EXPIRE 2
#define IPMAP_STATUS 3

// externer server, der der lokationdaten berechnet
#define IPLOOKUP_HOST "127.0.0.1"
#define IPLOOKUP_PORT 8711
#define IPLOOKUP_SAVE "/p/daemon/save/iplookup"

// moegliche statuswerte (platz zum zaehlen der anfragen gelassen)
#define STATUS_QUERYING      1
#define STATUS_AUTHORITATIVE 128

// so lange werden die daten im cache gehalten
#define CACHE_TIME    86400  /* 1 day */

// Ab dieser Groesse betrache ich den cache als "gross genug",
// um einen cache update in etappen zu rechtfertigen.
#define LARGE_CACHE_LIMIT 2000

// so lange sind wir bereit auf die antwort einer anfrage beim server zu warten
#define QUERY_TIME    60     /* 1 min */

#include <config.h>
#if MUDNAME == "MorgenGrauen"
#define LOG(x) log_file("rumata/iplookup.log",strftime("%Y-%m-%d %H:%M:%S: ")+(x)+"\n")
#else
#define LOG(x)
#endif

// PROTOTYPES
static void expire_cache_small();
static void expire_cache_large( string* keys );

// IMPLEMENTATION

protected void create() {
	seteuid(getuid());
	restore_object( IPLOOKUP_SAVE );

	if( !mappingp(ipmap) || widthof(ipmap)!=4 ) {
		ipmap = m_allocate( 0, 4 );
		LOG("restore failed, creating new ipmap");
	} else {
	  LOG(sprintf("created (%d entries)",sizeof(ipmap)));
	}
}

public void reset() {
	if( sizeof(ipmap) < LARGE_CACHE_LIMIT ) {
		expire_cache_small();
	} else {
		LOG(sprintf("reset %d ->",sizeof(ipmap)));
		expire_cache_large( m_indices(ipmap) );
	}
  set_next_reset(10800);
}

static int active_entry( string key, mixed* data ) {
	return time() < data[IPMAP_EXPIRE];
}

// Den cache auf einfache weise aufraeumen.
static  void expire_cache_small() {
	int s = sizeof(ipmap);
	ipmap = filter( ipmap, #'active_entry );
	save_object( IPLOOKUP_SAVE );
	LOG(sprintf("reset (%d -> %d)",s,sizeof(ipmap)));
}

// Kompliziertere routine, die den cache etappenweise abarbeitet.
static	void expire_cache_large( string* keys ) {
	if( !pointerp(keys) ) return;
	int next=0;
	foreach( string key: keys ) {
		if( get_eval_cost() < 100000 ) break;
		if( ipmap[key,IPMAP_EXPIRE] < time() ) {
			m_delete( ipmap, key );
		}
		next++;
	}
	LOG(sprintf("checking %d of %d",next,sizeof(keys)));
	if( next<sizeof(keys) ) {
		call_out( #'expire_cache_large, 6, keys[next..] );
	} else {
		save_object( IPLOOKUP_SAVE );
		LOG(sprintf("reset -> %d (done)",sizeof(ipmap)));
	}
}

#define SEARCHING "<auf der Suche...>"

/* Erzeugt einen temporaeren Eintrag, der fuer eine Suche steht.
 * Wenn die Antwort kommt, wird der Eintrag mit den entgueltigen
 * Daten ueberschrieben.
 */
static void make_request( string ipnum ) {
	send_udp( IPLOOKUP_HOST, IPLOOKUP_PORT, to_bytes(ipnum, "ASCII") );
	ipmap += ([ ipnum : ipnum ; SEARCHING ;
		time()+QUERY_TIME ; STATUS_QUERYING
	]);
}

/* Liefert zu einer gegebenen ipnum den Ort.
 * diese Funktion wird von simul_efun aufgerufen.
 * @param ipnum eine numerische ip-adresse oder ein interactive
 * @return den Ort (oder das Land) in dem sich die ip-adresse
 * laut externem Server befindet.
 */
public string country( string|object ipnum ) {
	string host,city;
	int expire,state;

	if( objectp(ipnum) ) {
		ipnum = query_ip_number(ipnum);
	}
	if( !stringp(ipnum) ) {
		return "<undefined>";
	}
	if( !m_contains( &host, &city, &expire, &state, ipmap, ipnum ) ) {
		make_request( ipnum );
		return SEARCHING;
	}

	return city;
}

/* Liefert zu einer gegebenen ipnum den Hostnamen.
 * diese Funktion wird von simul_efun aufgerufen.
 * @param ipnum eine numerische ip-adresse oder ein interactive
 * @return den Hostnamen der zu der angegebenen ip-adresse gehoert.
 * wenn der hostname nicht bekannt ist, wird die ipadresse zurueckgegeben.
 */
public string host( string|object ipnum ) {
	string host,city;
	int expire,state;

	if( objectp(ipnum) ) {
		ipnum = query_ip_number(ipnum);
	}
	if( !stringp(ipnum) ) {
		return "<undefined>";
	}
	if( !m_contains( &host, &city, &expire, &state, ipmap, ipnum ) ) {
		make_request( ipnum );
		return ipnum;
	}

	return host;
}

/* wird vom master aufgerufen, wenn eine antwort vom externen
 * iplookup dienst eintrudelt.
 */
public void update( string udp_reply ) {
	string* reply;
	if( previous_object()!=master() ) return;
	reply = explode(udp_reply,"\n");
	if( sizeof(reply)<4 ) return;

	if( reply[3] == "<unknown>" ) reply[3] = reply[1];
	if( reply[2] == "<unknown>" ) reply[2] = "irgendwoher";
	ipmap += ([ reply[1] : reply[3] ; reply[2] ; time()+CACHE_TIME ;
		STATUS_AUTHORITATIVE ]);
	//save_object( IPLOOKUP_SAVE );
}

int remove(int silent) {
  save_object( IPLOOKUP_SAVE );
  destruct(this_object());
  return 1;
}

// DEBUGGING CODE

#if 0
public void dump( string key, mixed* data ) {
	printf( "%s: %s (%s) s=%d bis %d\n", key, data[0], data[1],
		data[3], data[2] );
}

public void load(string s) {
	restore_object(s);
	if( !mappingp(ipmap) || widthof(ipmap)!=4 ) {
		ipmap = m_allocate( 0, 4 );
		LOG("restore failed, creating new ipmap");
	} else {
	  LOG(sprintf("created (%d entries)",sizeof(ipmap)));
	}
}

public void debug() {
	map( ipmap, #'dump );
	printf( "= %d Eintraege\n", sizeof(ipmap) );
}
#endif
