/*-------------------------------------------------------------------------
 * drawElements Utility Library
 * ----------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief File abstraction.
 *//*--------------------------------------------------------------------*/

#include "deFile.h"
#include "deMemory.h"

#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_SYMBIAN)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

struct deFile_s
{
	int fd;
};

deBool deFileExists (const char* filename)
{
	struct stat st;
	int result = stat(filename, &st);
	return result == 0;
}

deBool deDeleteFile (const char* filename)
{
	return unlink(filename) == 0;
}

deFile* deFile_createFromHandle (deUintptr handle)
{
	int		fd		= (int)handle;
	deFile* file	= (deFile*)deCalloc(sizeof(deFile));
	if (!file)
	{
		close(fd);
		return file;
	}
	
	file->fd = fd;
	return file;
}

static int mapOpenMode (deFileMode mode)
{
	int flag = 0;

	/* Read, write or read and write access is required. */
	DE_ASSERT((mode & DE_FILEMODE_READ) != 0 || ((mode & DE_FILEMODE_WRITE) != 0));

	/* Create, open or create and open mode is required. */
	DE_ASSERT((mode & DE_FILEMODE_OPEN) != 0 || ((mode & DE_FILEMODE_CREATE) != 0));

	/* Require write when using create. */
	DE_ASSERT(!(mode & DE_FILEMODE_CREATE) || (mode & DE_FILEMODE_WRITE));

	/* Require write and open when using truncate */
	DE_ASSERT(!(mode & DE_FILEMODE_TRUNCATE) || ((mode & DE_FILEMODE_WRITE) && (mode & DE_FILEMODE_OPEN)));

	if (mode & DE_FILEMODE_READ)
		flag |= O_RDONLY;

	if (mode & DE_FILEMODE_WRITE)
		flag |= O_WRONLY;

	if (mode & DE_FILEMODE_TRUNCATE)
		flag |= O_TRUNC;

	if (mode & DE_FILEMODE_CREATE)
		flag |= O_CREAT;

	if (!(mode & DE_FILEMODE_OPEN))
		flag |= O_EXCL;

	return flag;
}

deFile* deFile_create (const char* filename, deUint32 mode)
{
	int fd = open(filename, mapOpenMode(mode), 0777);
	if (fd >= 0)
		return deFile_createFromHandle((deUintptr)fd);
	else
		return DE_NULL;
}

void deFile_destroy (deFile* file)
{
	close(file->fd);
	deFree(file);
}

deBool deFile_setFlags (deFile* file, deUint32 flags)
{
	/* Non-blocking. */
	{
		int oldFlags = fcntl(file->fd, F_GETFL, 0);
		int newFlags = (flags & DE_FILE_NONBLOCKING) ? (oldFlags | O_NONBLOCK) : (oldFlags & ~O_NONBLOCK);
		if (fcntl(file->fd, F_SETFL, newFlags) != 0)
			return DE_FALSE;
	}
	
	/* Close on exec. */
	{
		int oldFlags = fcntl(file->fd, F_GETFD, 0);
		int newFlags = (flags & DE_FILE_CLOSE_ON_EXEC) ? (oldFlags | FD_CLOEXEC) : (oldFlags & ~FD_CLOEXEC);
		if (fcntl(file->fd, F_SETFD, newFlags) != 0)
			return DE_FALSE;
	}
	
	return DE_TRUE;
}

static int mapSeekPosition (deFilePosition position)
{
	switch (position)
	{
		case DE_FILEPOSITION_BEGIN:		return SEEK_SET;
		case DE_FILEPOSITION_END:		return SEEK_END;
		case DE_FILEPOSITION_CURRENT:	return SEEK_CUR;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

deBool deFile_seek (deFile* file, deFilePosition base, deInt64 offset)
{
	return lseek(file->fd, offset, mapSeekPosition(base)) >= 0;
}

deInt64 deFile_getPosition (const deFile* file)
{
	return lseek(file->fd, 0, SEEK_CUR);
}

deInt64 deFile_getSize (const deFile* file)
{
	deInt64 size	= 0;
	deInt64 curPos	= lseek(file->fd, 0, SEEK_CUR);

	if (curPos < 0)
		return -1;

	if (lseek(file->fd, -1, SEEK_END) < 0)
		return -1;

	size = lseek(file->fd, 0, SEEK_CUR);
	lseek(file->fd, curPos, SEEK_SET);
	
	return size;
}

static deFileResult mapReadWriteResult (deInt64 numBytes)
{
	if (numBytes > 0)
		return DE_FILERESULT_SUCCESS;
	else if (numBytes == 0)
		return DE_FILERESULT_END_OF_FILE;
	else
		return errno == EAGAIN ? DE_FILERESULT_WOULD_BLOCK : DE_FILERESULT_ERROR;
}

deFileResult deFile_read (deFile* file, void* buf, deInt64 bufSize, deInt64* numReadPtr)
{
	deInt64 numRead = read(file->fd, buf, bufSize);
	
	if (numReadPtr)
		*numReadPtr = numRead;

	return mapReadWriteResult(numRead);
}

deFileResult deFile_write (deFile* file, const void* buf, deInt64 bufSize, deInt64* numWrittenPtr)
{
	deInt64 numWritten = write(file->fd, buf, bufSize);
	
	if (numWrittenPtr)
		*numWrittenPtr = numWritten;

	return mapReadWriteResult(numWritten);
}

#elif (DE_OS == DE_OS_WIN32)

#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

struct deFile_s
{
	HANDLE handle;
};

deBool deFileExists (const char* filename)
{
	return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
}

deBool deDeleteFile (const char* filename)
{
	return DeleteFile(filename) == TRUE;
}

deFile* deFile_createFromHandle (deUintptr handle)
{
	deFile* file = (deFile*)deCalloc(sizeof(deFile));
	if (!file)
	{
		CloseHandle((HANDLE)handle);
		return file;
	}
	
	file->handle = (HANDLE)handle;
	return file;
}

deFile* deFile_create (const char* filename, deUint32 mode)
{
	DWORD	access		= 0;
	DWORD	create		= OPEN_EXISTING;
	HANDLE	handle		= DE_NULL;

	/* Read, write or read and write access is required. */
	DE_ASSERT((mode & DE_FILEMODE_READ) != 0 || ((mode & DE_FILEMODE_WRITE) != 0));

	/* Create, open or create and open mode is required. */
	DE_ASSERT((mode & DE_FILEMODE_OPEN) != 0 || ((mode & DE_FILEMODE_CREATE) != 0));

	/* Require write when using create. */
	DE_ASSERT(!(mode & DE_FILEMODE_CREATE) || (mode & DE_FILEMODE_WRITE));

	/* Require write and open when using truncate */
	DE_ASSERT(!(mode & DE_FILEMODE_TRUNCATE) || ((mode & DE_FILEMODE_WRITE) && (mode & DE_FILEMODE_OPEN)));


	if (mode & DE_FILEMODE_READ)
		access |= GENERIC_READ;

	if (mode & DE_FILEMODE_WRITE)
		access |= GENERIC_WRITE;

	if ((mode & DE_FILEMODE_TRUNCATE))
	{
		if ((mode & DE_FILEMODE_CREATE) && (mode & DE_FILEMODE_OPEN))
			create = CREATE_ALWAYS;
		else if (mode & DE_FILEMODE_OPEN)
			create = TRUNCATE_EXISTING;
		else
			DE_ASSERT(DE_FALSE);
	}
	else
	{
		if ((mode & DE_FILEMODE_CREATE) && (mode & DE_FILEMODE_OPEN))
			create = OPEN_ALWAYS;
		else if (mode & DE_FILEMODE_CREATE)
			create = CREATE_NEW;
		else if (mode & DE_FILEMODE_OPEN)
			create = OPEN_EXISTING;
		else
			DE_ASSERT(DE_FALSE);
	}

	handle = CreateFile(filename, access, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, DE_NULL, create, FILE_ATTRIBUTE_NORMAL, DE_NULL);
	if (handle == INVALID_HANDLE_VALUE)
		return DE_NULL;

	return deFile_createFromHandle((deUintptr)handle);
}

void deFile_destroy (deFile* file)
{
	CloseHandle(file->handle);
	deFree(file);
}

deBool deFile_setFlags (deFile* file, deUint32 flags)
{
	/* Non-blocking. */
	if (flags & DE_FILE_NONBLOCKING)
		return DE_FALSE; /* Not supported. */
	
	/* Close on exec. */
	if (!SetHandleInformation(file->handle, HANDLE_FLAG_INHERIT, (flags & DE_FILE_CLOSE_ON_EXEC) ? HANDLE_FLAG_INHERIT : 0))
		return DE_FALSE;

	return DE_TRUE;
}

deBool deFile_seek (deFile* file, deFilePosition base, deInt64 offset)
{
	DWORD	method		= 0;
	LONG	lowBits		= (LONG)(offset & 0xFFFFFFFFll);
	LONG	highBits	= (LONG)((offset >> 32) & 0xFFFFFFFFll);

	switch (base)
	{
		case DE_FILEPOSITION_BEGIN:		method = FILE_BEGIN;	break;
		case DE_FILEPOSITION_END:		method = FILE_END;		break;
		case DE_FILEPOSITION_CURRENT:	method = FILE_CURRENT;	break;
		default:
			DE_ASSERT(DE_FALSE);
			return DE_FALSE;
	}

	return SetFilePointer(file->handle, lowBits, &highBits, method) != INVALID_SET_FILE_POINTER;
}

deInt64 deFile_getPosition (const deFile* file)
{
	LONG	highBits	= 0;
	LONG	lowBits		= SetFilePointer(file->handle, 0, &highBits, FILE_CURRENT);

	return (deInt64)(((deUint64)highBits << 32) | (deUint64)lowBits);
}

deInt64 deFile_getSize (const deFile* file)
{
	DWORD	highBits	= 0;
	DWORD	lowBits		= GetFileSize(file->handle, &highBits);

	return (deInt64)(((deUint64)highBits << 32) | (deUint64)lowBits);
}

static deFileResult mapReadWriteResult (BOOL retVal, DWORD numBytes)
{
	if (retVal && numBytes > 0)
		return DE_FILERESULT_SUCCESS;
	else if (retVal && numBytes == 0)
		return DE_FILERESULT_END_OF_FILE;
	else
	{
		DWORD error = GetLastError();

		if (error == ERROR_HANDLE_EOF)
			return DE_FILERESULT_END_OF_FILE;
		else
			return DE_FILERESULT_ERROR;
	}
}

deFileResult deFile_read (deFile* file, void* buf, deInt64 bufSize, deInt64* numReadPtr)
{
	DWORD	bufSize32	= (DWORD)bufSize;
	DWORD	numRead32	= 0;
	BOOL	result;

	/* \todo [2011-10-03 pyry] 64-bit IO. */
	DE_ASSERT((deInt64)bufSize32 == bufSize);

	result = ReadFile(file->handle, buf, bufSize32, &numRead32, DE_NULL);

	if (numReadPtr)
		*numReadPtr = (deInt64)numRead32;

	return mapReadWriteResult(result, numRead32);
}

deFileResult deFile_write (deFile* file, const void* buf, deInt64 bufSize, deInt64* numWrittenPtr)
{
	DWORD	bufSize32		= (DWORD)bufSize;
	DWORD	numWritten32	= 0;
	BOOL	result;

	/* \todo [2011-10-03 pyry] 64-bit IO. */
	DE_ASSERT((deInt64)bufSize32 == bufSize);

	result = WriteFile(file->handle, buf, bufSize32, &numWritten32, DE_NULL);

	if (numWrittenPtr)
		*numWrittenPtr = (deInt64)numWritten32;

	return mapReadWriteResult(result, numWritten32);
}

#else
#	error Implement deFile for your OS.
#endif
