/*
 * Module/Library loadorder
 *
 * Copyright 1999 Bertho Stultiens
 */

#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "config.h"
#include "windef.h"
#include "options.h"
#include "loadorder.h"
#include "heap.h"
#include "options.h"
#include "module.h"
#include "elfdll.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(module)


/* #define DEBUG_LOADORDER */

#define LOADORDER_ALLOC_CLUSTER	32	/* Allocate with 32 entries at a time */

static module_loadorder_t default_loadorder;
static module_loadorder_t *module_loadorder = NULL;
static int nmodule_loadorder = 0;
static int nmodule_loadorder_alloc = 0;

static struct tagDllOverride {
	char *key,*value;
} DefaultDllOverrides[] = {
	{"kernel32,gdi32,user32",	"builtin"},
	{"krnl386,gdi,user",		"builtin"},
	{"toolhelp",			"builtin"},
	{"comdlg32,commdlg",		"elfdll,builtin,native"},
	{"version,ver",			"elfdll,builtin,native"},
	{"shell32,shell",		"builtin,native"},
	{"shlwapi",			"native,builtin"},
	{"lz32,lzexpand",		"builtin,native"},
	{"commctrl,comctl32",		"builtin,native"},
	{"wsock32,winsock",		"builtin"},
	{"advapi32,crtdll,ntdll",	"builtin,native"},
	{"mpr,winspool.drv",		"builtin,native"},
	{"ddraw,dinput,dsound",		"builtin,native"},
	{"winmm, mmsystem",		"builtin"},
	{"msvideo, msvfw32",		"builtin, native"},
	{"mcicda.drv, mciseq.drv",	"builtin, native"},
	{"mciwave.drv",			"builtin, native"},
	{"mciavi.drv, mcianim.drv",	"native, builtin"},
	{"msacm.drv, midimap.drv",      "builtin, native"},
	{"w32skrnl",			"builtin"},
	{"wnaspi32,wow32",		"builtin"},
	{"system,display,wprocs	",	"builtin"},
	{"wineps",			"builtin"},
	/* we have to use libglide2x.so instead of glide2x.dll ... */
	{"glide2x",			"so,native"},
	{NULL,NULL},
};

/***************************************************************************
 *	cmp_sort_func	(internal, static)
 *
 * Sorting and comparing function used in sort and search of loadorder
 * entries.
 */
static int cmp_sort_func(const void *s1, const void *s2)
{
	return strcasecmp(((module_loadorder_t *)s1)->modulename, ((module_loadorder_t *)s2)->modulename);
}


/***************************************************************************
 *	get_tok	(internal, static)
 *
 * strtok wrapper for non-destructive buffer writing.
 * NOTE: strtok is not reentrant and therefore this code is neither.
 */
static char *get_tok(const char *str, const char *delim)
{
	static char *buf = NULL;
	char *cptr;

	if(!str && !buf)
		return NULL;

	if(str && buf)
	{
		HeapFree(SystemHeap, 0, buf);
		buf = NULL;
	}

	if(str && !buf)
	{
		buf = HEAP_strdupA(SystemHeap, 0, str);
		cptr = strtok(buf, delim);
	}
	else
	{
		cptr = strtok(NULL, delim);
	}

	if(!cptr)
	{
		HeapFree(SystemHeap, 0, buf);
		buf = NULL;
	}
	return cptr;
}


/***************************************************************************
 *	ParseLoadOrder	(internal, static)
 *
 * Parses the loadorder options from the configuration and puts it into
 * a structure.
 */
static BOOL ParseLoadOrder(char *order, module_loadorder_t *mlo)
{
	char *cptr;
	int n = 0;

	memset(mlo->loadorder, 0, sizeof(mlo->loadorder));

	cptr = get_tok(order, ", \t");
	while(cptr)
	{
		char type = MODULE_LOADORDER_INVALID;

		if(n >= MODULE_LOADORDER_NTYPES)
		{
			ERR("More than existing %d module-types specified, rest ignored", MODULE_LOADORDER_NTYPES);
			break;
		}

		switch(*cptr)
		{
		case 'N':	/* Native */
		case 'n': type = MODULE_LOADORDER_DLL; break;

		case 'E':	/* Elfdll */
		case 'e': type = MODULE_LOADORDER_ELFDLL; break;

		case 'S':	/* So */
		case 's': type = MODULE_LOADORDER_SO; break;

		case 'B':	/* Builtin */
		case 'b': type = MODULE_LOADORDER_BI; break;

		default:
			ERR("Invalid load order module-type '%s', ignored\n", cptr);
		}

		if(type != MODULE_LOADORDER_INVALID)
		{
			mlo->loadorder[n++] = type;
		}
		cptr = get_tok(NULL, ", \t");
	}
	return TRUE;
}


/***************************************************************************
 *	AddLoadOrder	(internal, static)
 *
 * Adds an entry in the list of overrides. If the entry exists then the
 * override parameter determines whether it will be overwriten.
 */
static BOOL AddLoadOrder(module_loadorder_t *plo, BOOL override)
{
	int i;

	/* TRACE(module, "'%s' -> %08lx\n", plo->modulename, *(DWORD *)(plo->loadorder)); */

	for(i = 0; i < nmodule_loadorder; i++)
	{
		if(!cmp_sort_func(plo, &module_loadorder[i]))
		{
			if(!override)
				ERR("Module '%s' is already in the list of overrides, using first definition\n", plo->modulename);
			else
				memcpy(module_loadorder[i].loadorder, plo->loadorder, sizeof(plo->loadorder));
			return TRUE;
		}
	}

	if(nmodule_loadorder >= nmodule_loadorder_alloc)
	{
		/* No space in current array, make it larger */
		nmodule_loadorder_alloc += LOADORDER_ALLOC_CLUSTER;
		module_loadorder = (module_loadorder_t *)HeapReAlloc(SystemHeap,
								     0,
								     module_loadorder,
								     nmodule_loadorder_alloc * sizeof(module_loadorder_t));
		if(!module_loadorder)
		{
			MESSAGE("Virtual memory exhausted\n");
			exit(1);
		}
	}
	memcpy(module_loadorder[nmodule_loadorder].loadorder, plo->loadorder, sizeof(plo->loadorder));
	module_loadorder[nmodule_loadorder].modulename = HEAP_strdupA(SystemHeap, 0, plo->modulename);
	nmodule_loadorder++;
	return TRUE;
}


/***************************************************************************
 *	AddLoadOrderSet	(internal, static)
 *
 * Adds an set of entries in the list of overrides from the key parameter.
 * If the entry exists then the override parameter determines whether it
 * will be overwriten.
 */
static BOOL AddLoadOrderSet(char *key, char *order, BOOL override)
{
	module_loadorder_t ldo;
	char *cptr;

	/* Parse the loadorder before the rest because strtok is not reentrant */
	if(!ParseLoadOrder(order, &ldo))
		return FALSE;

	cptr = get_tok(key, ", \t");
	while(cptr)
	{
		char *ext = strrchr(cptr, '.');
		if(ext)
		{
			if(strlen(ext) == 4 && (!strcasecmp(ext, ".dll") || !strcasecmp(ext, ".exe")))
				MESSAGE("Warning: Loadorder override '%s' contains an extension and might not be found during lookup\n", cptr);
		}

		ldo.modulename = cptr;
		if(!AddLoadOrder(&ldo, override))
			return FALSE;
		cptr = get_tok(NULL, ", \t");
	}
	return TRUE;
}


/***************************************************************************
 *	ParseCommandlineOverrides	(internal, static)
 *
 * The commandline is in the form:
 * name[,name,...]=native[,b,...][:...]
 */
static BOOL ParseCommandlineOverrides(void)
{
	char *cpy;
	char *key;
	char *next;
	char *value;
	BOOL retval = TRUE;

	if(!Options.dllFlags)
		return TRUE;

	cpy = HEAP_strdupA(SystemHeap, 0, Options.dllFlags);
	key = cpy;
	next = key;
	for(; next; key = next)
	{
		next = strchr(key, ':');
		if(next)
		{
			*next = '\0';
			next++;
		}
		value = strchr(key, '=');
		if(!value)
		{
			retval = FALSE;
			goto endit;
		}
		*value = '\0';
		value++;

		TRACE("Commandline override '%s' = '%s'\n", key, value);
		
		if(!AddLoadOrderSet(key, value, TRUE))
		{
			retval = FALSE;
			goto endit;
		}
	}
endit:
	HeapFree(SystemHeap, 0, cpy);
	return retval;;
}


/***************************************************************************
 *	MODULE_InitLoadOrder	(internal)
 *
 * Initialize the load order from the wine.conf file.
 * The section has tyhe following format:
 * Section:
 *	[DllDefaults]
 *
 * Keys:
 *	EXTRA_LD_LIBRARY_PATH=/usr/local/lib/wine[:/more/path/to/search[:...]]
 * The path will be appended to any existing LD_LIBRARY_PATH from the 
 * environment (see note in code below).
 *
 *	DefaultLoadOrder=native,elfdll,so,builtin
 * A comma seperated list of module-types to try to load in that specific
 * order. The DefaultLoadOrder key is used as a fallback when a module is
 * not specified explicitely. If the DefaultLoadOrder key is not found, 
 * then the order "dll,elfdll,so,bi" is used
 * The possible module-types are:
 *	- native	Native windows dll files
 *	- elfdll	Dlls encapsulated in .so libraries
 *	- so		Native .so libraries mapped to dlls
 *	- builtin	Built-in modules
 *
 * Case is not important and only the first letter of each type is enough to
 * identify the type n[ative], e[lfdll], s[o], b[uiltin]. Also whitespace is
 * ignored.
 * E.g.:
 * 	n,el	,s , b
 * is equal to:
 *	native,elfdll,so,builtin
 *
 * Section:
 *	[DllOverrides]
 *
 * Keys:
 * There are no explicit keys defined other than module/library names. A comma
 * separated list of modules is followed by an assignment of the load-order
 * for these specific modules. See above for possible types. You should not
 * specify an extension.
 * Examples:
 * kernel32, gdi32, user32 = builtin
 * kernel, gdi, user = builtin
 * comdlg32 = elfdll, native, builtin
 * commdlg = native, builtin
 * version, ver = elfdll, native, builtin
 *
 * Section:
 *	[DllPairs]
 *
 * Keys:
 * This is a simple pairing in the form 'name1 = name2'. It is supposed to
 * identify the dlls that cannot live without eachother unless they are
 * loaded in the same format. Examples are common dialogs and controls,
 * shell, kernel, gdi, user, etc...
 * The code will issue a warning if the loadorder of these pairs are different
 * and might cause hard-to-find bugs due to incompatible pairs loaded at
 * run-time. Note that this pairing gives *no* guarantee that the pairs
 * actually get loaded as the same type, nor that the correct versions are
 * loaded (might be implemented later). It merely notes obvious trouble.
 * Examples:
 * kernel = kernel32
 * commdlg = comdlg32
 *
 */

#define BUFFERSIZE	1024

BOOL MODULE_InitLoadOrder(void)
{
	char buffer[BUFFERSIZE];
	int nbuffer;

#if defined(HAVE_DL_API)
	/* Get/set the new LD_LIBRARY_PATH */
	nbuffer = PROFILE_GetWineIniString("DllDefaults", "EXTRA_LD_LIBRARY_PATH", "", buffer, sizeof(buffer));

	if(nbuffer)
	{
		extra_ld_library_path = HEAP_strdupA(SystemHeap, 0, buffer);
		TRACE("Setting extra LD_LIBRARY_PATH=%s\n", buffer);
	}
#endif

	/* Get the default load order */
	nbuffer = PROFILE_GetWineIniString("DllDefaults", "DefaultLoadOrder", "n,e,s,b", buffer, sizeof(buffer));
	if(!nbuffer)
	{
		MESSAGE("MODULE_InitLoadOrder: misteriously read nothing from default loadorder\n");
		return FALSE;
	}

	TRACE("Setting default loadorder=%s\n", buffer);

	if(!ParseLoadOrder(buffer, &default_loadorder))
		return FALSE;
	default_loadorder.modulename = "<none>";

	{
	    int i;
	    for (i=0;DefaultDllOverrides[i].key;i++)
		AddLoadOrderSet(
		    DefaultDllOverrides[i].key,
		    DefaultDllOverrides[i].value,
		    FALSE
		);
	}

	/* Read the explicitely defined orders for specific modules as an entire section */
	nbuffer = PROFILE_GetWineIniString("DllOverrides", NULL, "", buffer, sizeof(buffer));
	if(nbuffer == BUFFERSIZE-2)
	{
		ERR("BUFFERSIZE %d is too small to read [DllOverrides]. Needs to grow in the source\n", BUFFERSIZE);
		return FALSE;
	}
	if(nbuffer)
	{
		/* We only have the keys in the buffer, not the values */
		char *key;
		char value[BUFFERSIZE];
		char *next;

		for(key = buffer; *key; key = next)
		{
			next = key + strlen(key) + 1;

			nbuffer = PROFILE_GetWineIniString("DllOverrides", key, "", value, sizeof(value));
			if(!nbuffer)
			{
				ERR("Module(s) '%s' will always fail to load. Are you sure you want this?\n", key);
				value[0] = '\0';	/* Just in case */
			}
			if(nbuffer == BUFFERSIZE-2)
			{
				ERR("BUFFERSIZE %d is too small to read [DllOverrides] key '%s'. Needs to grow in the source\n", BUFFERSIZE, key);
				return FALSE;
			}

			TRACE("Key '%s' uses override '%s'\n", key, value);

                        if(!AddLoadOrderSet(key, value, TRUE))
				return FALSE;
		}
	}

	/* Add the commandline overrides to the pool */
	if(!ParseCommandlineOverrides())
	{
		MESSAGE(	"Syntax: -dll name[,name[,...]]={native|elfdll|so|builtin}[,{n|e|s|b}[,...]][:...]\n"
			"    - 'name' is the name of any dll without extension\n"
			"    - the order of loading (native, elfdll, so and builtin) can be abbreviated\n"
			"      with the first letter\n"
			"    - different loadorders for different dlls can be specified by seperating the\n"
			"      commandline entries with a ':'\n"
			"    Example:\n"
			"    -dll comdlg32,commdlg=n:shell,shell32=b\n"
		   );
		return FALSE;
	}

	/* Sort the array for quick lookup */
	qsort(module_loadorder, nmodule_loadorder, sizeof(module_loadorder[0]), cmp_sort_func);

	/* Check the pairs of dlls */
	nbuffer = PROFILE_GetWineIniString("DllPairs", NULL, "", buffer, sizeof(buffer));
	if(nbuffer == BUFFERSIZE-2)
	{
		ERR("BUFFERSIZE %d is too small to read [DllPairs]. Needs to grow in the source\n", BUFFERSIZE);
		return FALSE;
	}
	if(nbuffer)
	{
		/* We only have the keys in the buffer, not the values */
		char *key;
		char value[BUFFERSIZE];
		char *next;

		for(key = buffer; *key; key = next)
		{
			module_loadorder_t *plo1, *plo2;

			next = key + strlen(key) + 1;

			nbuffer = PROFILE_GetWineIniString("DllPairs", key, "", value, sizeof(value));
			if(!nbuffer)
			{
				ERR("Module pair '%s' is not associated with another module?\n", key);
				continue;
			}
			if(nbuffer == BUFFERSIZE-2)
			{
				ERR("BUFFERSIZE %d is too small to read [DllPairs] key '%s'. Needs to grow in the source\n", BUFFERSIZE, key);
				return FALSE;
			}

			plo1 = MODULE_GetLoadOrder(key);
			plo2 = MODULE_GetLoadOrder(value);
			assert(plo1 && plo2);

			if(memcmp(plo1->loadorder, plo2->loadorder, sizeof(plo1->loadorder)))
				MESSAGE("Warning: Modules '%s' and '%s' have different loadorder which may cause trouble\n", key, value);
		}
	}

	if(TRACE_ON(module))
	{
		int i, j;
		static char types[6] = "-NESB";

		for(i = 0; i < nmodule_loadorder; i++)
		{
			DPRINTF("%3d: %-12s:", i, module_loadorder[i].modulename);
			for(j = 0; j < MODULE_LOADORDER_NTYPES; j++)
				DPRINTF(" %c", types[module_loadorder[i].loadorder[j] % (MODULE_LOADORDER_NTYPES+1)]);
			DPRINTF("\n");
		}
	}

	return TRUE;
}


/***************************************************************************
 *	MODULE_GetLoadOrder	(internal)
 *
 * Locate the loadorder of a module.
 * Any path is stripped from the path-argument and so are the extension
 * '.dll' and '.exe'. A lookup in the table can yield an override for
 * the specific dll. Otherwise the default load order is returned.
 */
module_loadorder_t *MODULE_GetLoadOrder(const char *path)
{
	module_loadorder_t lo, *tmp;
	char fname[256];
	char *cptr;
	char *name;
	int len;

	assert(path != NULL);

	/* Strip path information */
	cptr = strrchr(path, '\\');
	if(!cptr)
		name = strrchr(path, '/');
	else
		name = strrchr(cptr, '/');

	if(!name)
		name = cptr ? cptr+1 : (char *)path;
	else
		name++;

	if((cptr = strchr(name, ':')) != NULL)	/* Also strip drive if in format 'C:MODULE.DLL' */
		name = cptr+1;

	len = strlen(name);
	if(len >= sizeof(fname) || len <= 0)
	{
		ERR("Path '%s' -> '%s' reduces to zilch or just too large...\n", path, name);
		return &default_loadorder;
	}

	strcpy(fname, name);
	if(len >= 4 && (!lstrcmpiA(fname+len-4, ".dll") || !lstrcmpiA(fname+len-4, ".exe")))
		fname[len-4] = '\0';

	lo.modulename = fname;
	tmp = bsearch(&lo, module_loadorder, nmodule_loadorder, sizeof(module_loadorder[0]), cmp_sort_func);

	TRACE("Looking for '%s' (%s), found '%s'\n", path, fname, tmp ? tmp->modulename : "<nothing>");

	if(!tmp)
		return &default_loadorder;
	return tmp;
}

