#include "Python.h"
#include "osdefs.h"
#include <windows.h>

/* PREFIX and EXEC_PREFIX are meaningless on Windows */

#ifndef PREFIX
#define PREFIX ""
#endif

#ifndef EXEC_PREFIX
#define EXEC_PREFIX ""
#endif

/*
This is a special Win32 version of getpath.

* There is no default path.  There is nothing even remotely resembling
  a standard location.  Maybe later "Program Files/Python", but not yet.

* The Registry is used as the primary store for the Python path.

* The environment variable PYTHONPATH _overrides_ the registry.  This should
  allow a "standard" Python environment, but allow you to manually setup
  another (eg, a beta version).

*/

BOOL PyWin_IsWin32s()
{
	static BOOL bIsWin32s = -1; // flag as "not yet looked"

	if (bIsWin32s==-1) {
		OSVERSIONINFO ver;
		ver.dwOSVersionInfoSize = sizeof(ver);
		GetVersionEx(&ver);
		bIsWin32s = ver.dwPlatformId == VER_PLATFORM_WIN32s;
	}
	return bIsWin32s;
}

/* Load a PYTHONPATH value from the registry
   Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER

   Returns NULL, or a pointer that should be free'd.
*/
static char *
getpythonregpath(HKEY keyBase, BOOL bWin32s)
{
	HKEY newKey = 0;
	DWORD nameSize = 0;
	DWORD dataSize = 0;
	DWORD numEntries = 0;
	LONG rc;
	char *retval = NULL;
	char *dataBuf;
	if ((rc=RegOpenKey(keyBase, "Software\\Python\\PythonCore\\" MS_DLL_ID "\\PythonPath", 
	                   &newKey))==ERROR_SUCCESS) {
		RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL, 
		                &numEntries, &nameSize, &dataSize, NULL, NULL );
	}
	if (bWin32s && numEntries==0 && dataSize==0) { /* must hardcode for Win32s */
		numEntries = 1;
		dataSize = 511;
	}
	if (numEntries) {
		/* Loop over all subkeys. */
		/* Win32s doesnt know how many subkeys, so we do
		   it twice */
		char keyBuf[MAX_PATH+1];
		int index = 0;
		int off = 0;
		for(index=0;;index++) {
			long reqdSize = 0;
			DWORD rc = RegEnumKey(newKey, index, keyBuf,MAX_PATH+1);
			if (rc) break;
			rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
			if (rc) break;
			if (bWin32s && reqdSize==0) reqdSize = 512;
			dataSize += reqdSize + 1; /* 1 for the ";" */
		}
		dataBuf = malloc(dataSize+1);
		if (dataBuf==NULL) return NULL; /* pretty serious?  Raise error? */
		/* Now loop over, grabbing the paths.  Subkeys before main library */
		for(index=0;;index++) {
			int adjust;
			long reqdSize = dataSize;
			DWORD rc = RegEnumKey(newKey, index, keyBuf,MAX_PATH+1);
			if (rc) break;
			rc = RegQueryValue(newKey, keyBuf, dataBuf+off, &reqdSize);
			if (rc) break;
			adjust = strlen(dataBuf+off);
			dataSize -= adjust;
			off += adjust;
			dataBuf[off++] = ';';
			dataBuf[off] = '\0';
			dataSize--;
		}
		/* Additionally, win32s doesnt work as expected, so
		   the specific strlen() is required for 3.1. */
		rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
		if (rc==ERROR_SUCCESS) {
			if (strlen(dataBuf)==0)
				free(dataBuf);
			else
				retval = dataBuf; // caller will free
		}
		else
			free(dataBuf);
	}

	if (newKey)
		CloseHandle(newKey);
	return retval;
}
/* Return the initial python search path.  This is called once from
   initsys() to initialize sys.path.  The environment variable
   PYTHONPATH is fetched and the default path appended.  The default
   path may be passed to the preprocessor; if not, a system-dependent
   default is used. */

char *
Py_GetPath()
{
	char *path = getenv("PYTHONPATH");
	char *defpath = PYTHONPATH;
	static char *buf = NULL;
	char *p;
	int n;

	if (buf != NULL) {
		free(buf);
		buf = NULL;
	}

	if (path == NULL) {
		char *machinePath, *userPath;
		int machineLen, userLen;
		/* lookup the registry */
		BOOL bWin32s = PyWin_IsWin32s();

		if (bWin32s) { /* are we running under Windows 3.1 Win32s */
			/* only CLASSES_ROOT is supported */
			machinePath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE); 
			userPath = NULL;
		} else {
			machinePath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
			userPath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
		}
		if (machinePath==NULL && userPath==NULL) return defpath;
		machineLen = machinePath ? strlen(machinePath) : 0;
		userLen = userPath ? strlen(userPath) : 0;
		n = machineLen + userLen + 1;
		// this is a memory leak, as Python never frees it.  Only ever called once, so big deal!
		buf = malloc(n);
		if (buf == NULL)
			Py_FatalError("not enough memory to copy module search path");
		p = buf;
		*p = '\0';
		if (machineLen) {
			strcpy(p, machinePath);
			p += machineLen;
		}
		if (userLen) {
			if (machineLen)
				*p++ = DELIM;
			strcpy(p, userPath);
		}
		if (userPath) free(userPath);
		if (machinePath) free(machinePath);
	} else {
		
		buf = malloc(strlen(path)+1);
		if (buf == NULL)
			Py_FatalError("not enough memory to copy module search path");
		strcpy(buf, path);
	}
	return buf;
}

/* Similar for Makefile variables $prefix and $exec_prefix */

char *
Py_GetPrefix()
{
	return PREFIX;
}

char *
Py_GetExecPrefix()
{
	return EXEC_PREFIX;
}
