#ifndef _JS_CACHE_H_
#define _JS_CACHE_H_

#include "link_list.h"
#include "jscntxt.h"
#include "jsscript.h"

/* JS Compile Cache Stuff */
struct context_cache {
	JSContext	*cx;
	link_list_t	cache;
};

struct cache_data {
	char	filename[MAX_PATH+1];
	time_t	mtime,ctime;		/* st_mtime/st_ctime from last stat() call */
	off_t	size;				/* File size when loaded */
	ulong	runcount;			/* Number of times this script has been used */
	time_t	lastrun;			/* Time script was last ran */
	time_t	laststat;			/* Time of last call to stat() */
	JSScript	*script;
	int		running;			/* Count of currently running scripts */
	int		expired;			/* TRUE if last stat() makes this as stale and
								 * running was non-zero */
};

typedef struct {
	DWORD   size;				/* sizeof(js_cache_startup_t) */
	time_t	max_age;			/* Max age in seconds for lastrun */
	ulong	max_scripts;		/* Max number of scripts to hold in cache */
	time_t	stale_timeout;		/* Minimum time between calls to stat() */
	ulong	expire_period;		/* Time between servicing the exipry cache... milliseconds */
} js_cache_startup_t;

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Gets the compiled script from the cache if available and
 * laststat is less than stale time or a new stat() matches
 * the mtime, ctime, and size.
 * Compiles it and adds to the cache if not.
 * Increments running value.
 */
JSScript *js_get_compiled_script(JSContext *cx, char *filename);

/*
 * Starts the caching thread.  The caching thread periodically
 * checks the caches for entries to be expired.  They are expired
 * by weigth where weight=(age in seconds)/(number of times ran)
 * does NOT check the laststat nor does it do a stat().
 * It also does not expire an entry for which running is non-zero.
 */
void js_cache_thread(void *args);

/*
 * Decrements the running value, increments runcount, and updates
 * lastrun
 */
void js_script_done(struct cached_data *entry);

/*
 * Sets the expired member for any existing cached copies of filename
 * Required for self-modifying scripts.
 */
void js_cache_expire(char *filename);

/*
 * Creates a new cached runtime and context
 */
JSContext *js_get_cached_context(size_t maxbytes, size_t stacksize);
#ifdef __cplusplus
}
#endif

#endif
