/* libFLAC - Free Lossless Audio Codec library
 * Copyright (C) 2013-2016  Xiph.Org Foundation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of the Xiph.org Foundation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <io.h>
#include "share/windows_unicode_filenames.h"

/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */
static wchar_t *wchar_from_utf8(const char *str)
{
	wchar_t *widestr;
	int len;

	if (!str)
		return NULL;
	if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) == 0)
		return NULL;
	if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) == NULL)
		return NULL;
	if (MultiByteToWideChar(CP_UTF8, 0, str, -1, widestr, len) == 0) {
		free(widestr);
		widestr = NULL;
	}

	return widestr;
}


static FLAC__bool utf8_filenames = false;


void flac_internal_set_utf8_filenames(FLAC__bool flag)
{
	utf8_filenames = flag ? true : false;
}

FLAC__bool flac_internal_get_utf8_filenames(void)
{
	return utf8_filenames;
}

/* file functions */

FILE* flac_internal_fopen_utf8(const char *filename, const char *mode)
{
	if (!utf8_filenames) {
		return fopen(filename, mode);
	} else {
		wchar_t *wname = NULL;
		wchar_t *wmode = NULL;
		FILE *f = NULL;

		do {
			if (!(wname = wchar_from_utf8(filename))) break;
			if (!(wmode = wchar_from_utf8(mode))) break;
			f = _wfopen(wname, wmode);
		} while(0);

		free(wname);
		free(wmode);

		return f;
	}
}

int flac_internal_stat64_utf8(const char *path, struct __stat64 *buffer)
{
	if (!utf8_filenames) {
		return _stat64(path, buffer);
	} else {
		wchar_t *wpath;
		int ret;

		if (!(wpath = wchar_from_utf8(path))) return -1;
		ret = _wstat64(wpath, buffer);
		free(wpath);

		return ret;
	}
}

int flac_internal_chmod_utf8(const char *filename, int pmode)
{
	if (!utf8_filenames) {
		return _chmod(filename, pmode);
	} else {
		wchar_t *wname;
		int ret;

		if (!(wname = wchar_from_utf8(filename))) return -1;
		ret = _wchmod(wname, pmode);
		free(wname);

		return ret;
	}
}

int flac_internal_utime_utf8(const char *filename, struct utimbuf *times)
{
	if (!utf8_filenames) {
		return utime(filename, times);
	} else {
		wchar_t *wname;
		struct __utimbuf64 ut;
		int ret;

		if (!(wname = wchar_from_utf8(filename))) return -1;
		ut.actime = times->actime;
		ut.modtime = times->modtime;
		ret = _wutime64(wname, &ut);
		free(wname);

		return ret;
	}
}

int flac_internal_unlink_utf8(const char *filename)
{
	if (!utf8_filenames) {
		return _unlink(filename);
	} else {
		wchar_t *wname;
		int ret;

		if (!(wname = wchar_from_utf8(filename))) return -1;
		ret = _wunlink(wname);
		free(wname);

		return ret;
	}
}

int flac_internal_rename_utf8(const char *oldname, const char *newname)
{
	if (!utf8_filenames) {
		return rename(oldname, newname);
	} else {
		wchar_t *wold = NULL;
		wchar_t *wnew = NULL;
		int ret = -1;

		do {
			if (!(wold = wchar_from_utf8(oldname))) break;
			if (!(wnew = wchar_from_utf8(newname))) break;
			ret = _wrename(wold, wnew);
		} while(0);

		free(wold);
		free(wnew);

		return ret;
	}
}

HANDLE WINAPI flac_internal_CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
	if (!utf8_filenames) {
		return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
	} else {
		wchar_t *wname;
		HANDLE handle = INVALID_HANDLE_VALUE;

		if ((wname = wchar_from_utf8(lpFileName)) != NULL) {
			handle = CreateFileW(wname, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
			free(wname);
		}

		return handle;
	}
}
