#include <windows.h>

#include "zlib.h"

#include <stdio.h>
#include <stdarg.h>

#include "archive.h"

/* Convert unix-path to dos-path */
static void normpath(char *path)
{
	while (path && *path) {
		if (*path == '/')
			*path = '\\';
		++path;
	}
}

BOOL ensure_directory(char *pathname, char *new_part, NOTIFYPROC notify)
{
	while (new_part && *new_part && (new_part = strchr(new_part, '\\'))) {
		DWORD attr;
		*new_part = '\0';
		attr = GetFileAttributes(pathname);
		if (attr == -1) {
			/* nothing found */
			if (!CreateDirectory(pathname, NULL) && notify)
				notify(SYSTEM_ERROR,
				       "CreateDirectory (%s)", pathname);
			else
				notify(DIR_CREATED, pathname);
		}
		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
			;
		} else {
			SetLastError(183);
			if (notify)
				notify(SYSTEM_ERROR,
				       "CreateDirectory (%s)", pathname);
		}
		*new_part = '\\';
		++new_part;
	}
	return TRUE;
}

/* XXX Should better explicitely specify
 * uncomp_size and file_times instead of pfhdr!
 */
char *map_new_file(DWORD flags, char *filename,
		   char *pathname_part, int size,
		   WORD wFatDate, WORD wFatTime,
		   NOTIFYPROC notify)
{
	HANDLE hFile, hFileMapping;
	char *dst;
	FILETIME ft;

  try_again:
	if (!flags)
		flags = CREATE_NEW;
	hFile = CreateFile(filename,
			   GENERIC_WRITE | GENERIC_READ,
			   0, NULL,
			   flags,
			   FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE) {
		DWORD x = GetLastError();
		switch (x) {
		case ERROR_FILE_EXISTS:
			if (notify && notify(CAN_OVERWRITE, filename))
				hFile = CreateFile(filename,
						   GENERIC_WRITE|GENERIC_READ,
						   0, NULL,
						   CREATE_ALWAYS,
						   FILE_ATTRIBUTE_NORMAL,
						   NULL);
			else {
				if (notify)
					notify(FILE_OVERWRITTEN, filename);
				return NULL;
			}
			break;
		case ERROR_PATH_NOT_FOUND:
			if (ensure_directory(filename, pathname_part, notify))
				goto try_again;
			else
				return FALSE;
			break;
		default:
			SetLastError(x);
			break;
		}
	}
	if (hFile == INVALID_HANDLE_VALUE) {
		if (notify)
			notify (SYSTEM_ERROR, "CreateFile (%s)", filename);
		return NULL;
	}

	if (notify)
		notify(FILE_CREATED, filename);

	DosDateTimeToFileTime(wFatDate, wFatTime, &ft);
	SetFileTime(hFile, &ft, &ft, &ft);


	if (size == 0) {
		/* We cannot map a zero-length file (Also it makes
		   no sense */
		CloseHandle(hFile);
		return NULL;
	}

	hFileMapping = CreateFileMapping(hFile,
					 NULL, PAGE_READWRITE, 0, size, NULL);

	CloseHandle(hFile);

	if (hFileMapping == INVALID_HANDLE_VALUE) {
		if (notify)
			notify(SYSTEM_ERROR,
			       "CreateFileMapping (%s)", filename);
		return NULL;
	}

	dst = MapViewOfFile(hFileMapping,
			    FILE_MAP_WRITE, 0, 0, 0);

	CloseHandle(hFileMapping);

	if (!dst) {
		if (notify)
			notify(SYSTEM_ERROR, "MapViewOfFile (%s)", filename);
		return NULL;
	}
	return dst;
}


BOOL
extract_file(char *dst, char *src, int method, int comp_size,
	     int uncomp_size, NOTIFYPROC notify)
{
	z_stream zstream;
	int result;

	if (method == Z_DEFLATED) {
		int x;
		memset(&zstream, 0, sizeof(zstream));
		zstream.next_in = src;
		zstream.avail_in = comp_size+1;
		zstream.next_out = dst;
		zstream.avail_out = uncomp_size;

/* Apparently an undocumented feature of zlib: Set windowsize
   to negative values to supress the gzip header and be compatible with
   zip! */
		result = TRUE;
		if (Z_OK != (x = inflateInit2(&zstream, -15))) {
			if (notify)
				notify(ZLIB_ERROR,
				       "inflateInit2 returns %d", x);
			result = FALSE;
			goto cleanup;
		}
		if (Z_STREAM_END != (x = inflate(&zstream, Z_FINISH))) {
			if (notify)
				notify(ZLIB_ERROR,
				       "inflate returns %d", x);
			result = FALSE;
		}
	  cleanup:
		if (Z_OK != (x = inflateEnd(&zstream))) {
			if (notify)
				notify (ZLIB_ERROR,
					"inflateEnd returns %d", x);
			result = FALSE;
		}
	} else if (method == 0) {
		memcpy(dst, src, uncomp_size);
		result = TRUE;
	} else
		result = FALSE;
	UnmapViewOfFile(dst);
	return result;
}

/* Open a zip-compatible archive and extract all files
 * into the specified directory (which is assumed to exist)
 */
BOOL
unzip_archive(SCHEME *scheme, char *dirname, char *data, DWORD size,
	      NOTIFYPROC notify)
{
	int n;
	char pathname[MAX_PATH];
	char *new_part;

	/* read the end of central directory record */
	struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
						       (struct eof_cdir)];

	int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir -
		pe->ofsCDir;

	/* set position to start of central directory */
	int pos = arc_start + pe->ofsCDir;

	/* make sure this is a zip file */
	if (pe->tag != 0x06054b50)
		return FALSE;
    
	/* Loop through the central directory, reading all entries */
	for (n = 0; n < pe->nTotalCDir; ++n) {
		int i;
		char *fname;
		char *pcomp;
		char *dst;
		struct cdir *pcdir;
		struct fhdr *pfhdr;

		pcdir = (struct cdir *)&data[pos];
		pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header +
					     arc_start];

		if (pcdir->tag != 0x02014b50)
			return FALSE;
		if (pfhdr->tag != 0x04034b50)
			return FALSE;
		pos += sizeof(struct cdir);
		fname = (char *)&data[pos]; /* This is not null terminated! */
		pos += pcdir->fname_length + pcdir->extra_length +
			pcdir->comment_length;

		pcomp = &data[pcdir->ofs_local_header
			      + sizeof(struct fhdr)
			      + arc_start
			      + pfhdr->fname_length
			      + pfhdr->extra_length];

		/* dirname is the Python home directory (prefix) */
		strcpy(pathname, dirname);
		if (pathname[strlen(pathname)-1] != '\\')
			strcat(pathname, "\\");
		new_part = &pathname[lstrlen(pathname)];
		/* we must now match the first part of the pathname
		 * in the archive to a component in the installation
		 * scheme (PURELIB, PLATLIB, HEADERS, SCRIPTS, or DATA)
		 * and replace this part by the one in the scheme to use
		 */
		for (i = 0; scheme[i].name; ++i) {
			if (0 == strnicmp(scheme[i].name, fname,
					  strlen(scheme[i].name))) {
				char *rest;
				int len;
				
				/* length of the replaced part */
				int namelen = strlen(scheme[i].name);
				
				strcat(pathname, scheme[i].prefix);
				
				rest = fname + namelen;
				len = pfhdr->fname_length - namelen;
				
				if ((pathname[strlen(pathname)-1] != '\\')
				    && (pathname[strlen(pathname)-1] != '/'))
					strcat(pathname, "\\");
				/* Now that pathname ends with a separator,
				 * we must make sure rest does not start with
				 * an additional one.
				 */
				if ((rest[0] == '\\') || (rest[0] == '/')) {
					++rest;
					--len;
				}

				strncat(pathname, rest, len);
				goto Done;
			}
		}
		/* no prefix to replace found, go unchanged */
		strncat(pathname, fname, pfhdr->fname_length);
	  Done:
		normpath(pathname);
		if (pathname[strlen(pathname)-1] != '\\') {
			/*
			 * The local file header (pfhdr) does not always
			 * contain the compressed and uncompressed sizes of
			 * the data depending on bit 3 of the flags field.  So
			 * it seems better to use the data from the central
			 * directory (pcdir).
			 */
			dst = map_new_file(0, pathname, new_part,
					   pcdir->uncomp_size,
					   pcdir->last_mod_file_date,
					   pcdir->last_mod_file_time, notify);
			if (dst) {
				if (!extract_file(dst, pcomp, pfhdr->method,
						  pcdir->comp_size,
						  pcdir->uncomp_size,
						  notify))
					return FALSE;
			} /* else ??? */
		}
		if (notify)
			notify(NUM_FILES, new_part, (int)pe->nTotalCDir,
			       (int)n+1);
	}
	return TRUE;
}
