/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include <errno.h>
#include <string>
#include <sstream>
#include <cstring>

#ifdef _WIN32
#  include <windows.h>
#  include <io.h>
#elif defined(__APPLE__)
#  include <mach-o/dyld.h>
#  include <unistd.h>
#else
#  include <unistd.h>
#endif

#ifdef __FreeBSD__
#  include <sys/sysctl.h>
#endif

#include <limits.h>

#if defined(__linux__) || defined(__CYGWIN__)
std::string proc_self_dirname()
{
	char path[PATH_MAX];
	ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path));
	if (buflen < 0) {
		fprintf(stderr, "fatal error: readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	while (buflen > 0 && path[buflen-1] != '/')
		buflen--;
	return std::string(path, buflen);
}
#elif defined(__FreeBSD__)
std::string proc_self_dirname()
{
	int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
	size_t buflen;
	char *buffer;
	std::string path;
	if (sysctl(mib, 4, NULL, &buflen, NULL, 0) != 0) {
		fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	buffer = (char*)malloc(buflen);
	if (buffer == NULL) {
		fprintf(stderr, "fatal error: malloc failed: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	if (sysctl(mib, 4, buffer, &buflen, NULL, 0) != 0) {
		fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	while (buflen > 0 && buffer[buflen-1] != '/')
		buflen--;
	path.assign(buffer, buflen);
	free(buffer);
	return path;
}
#elif defined(__APPLE__)
std::string proc_self_dirname()
{
	char *path = NULL;
	uint32_t buflen = 0;
	while (_NSGetExecutablePath(path, &buflen) != 0)
		path = (char *) realloc((void *) path, buflen);
	while (buflen > 0 && path[buflen-1] != '/')
		buflen--;
	return std::string(path, buflen);
}
#elif defined(_WIN32)
std::string proc_self_dirname()
{
	int i = 0;
#  ifdef __MINGW32__
	char longpath[MAX_PATH + 1];
	char shortpath[MAX_PATH + 1];
#  else
	WCHAR longpath[MAX_PATH + 1];
	TCHAR shortpath[MAX_PATH + 1];
#  endif
	if (!GetModuleFileName(0, longpath, MAX_PATH+1)) {
		fprintf(stderr, "fatal error: GetModuleFileName() failed.\n");
		exit(EXIT_FAILURE);
	}
	if (!GetShortPathName(longpath, shortpath, MAX_PATH+1)) {
		fprintf(stderr, "fatal error: GetShortPathName() failed.\n");
		exit(EXIT_FAILURE);
	}
	while (shortpath[i] != 0)
		i++;
	while (i > 0 && shortpath[i-1] != '/' && shortpath[i-1] != '\\')
		shortpath[--i] = 0;
	std::string path;
	for (i = 0; shortpath[i]; i++)
		path += char(shortpath[i]);
	return path;
}
#elif defined(EMSCRIPTEN)
std::string proc_self_dirname()
{
	return "/";
}
#else
	#error Dont know how to determine process executable base path!
#endif

bool file_test_open(std::string path)
{
	FILE *fdb = fopen(path.c_str(), "r");
	if (fdb == nullptr) {
		return false;
	}
	fclose(fdb);
	return true;
}

extern bool verbose;

std::string find_chipdb(std::string config_device)
{
	if (PREFIX[0] == '~' && PREFIX[1] == '/') {
		std::string homepath;
#ifdef _WIN32
		if (getenv("USERPROFILE") != nullptr) {
			homepath += getenv("USERPROFILE");
		}
		else {
			if (getenv("HOMEDRIVE") != nullptr &&
			    getenv("HOMEPATH") != nullptr) {
				homepath += getenv("HOMEDRIVE");
				homepath += getenv("HOMEPATH");
			}
		}
#else
		homepath += getenv("HOME");
#endif
		homepath += std::string(PREFIX + 1) + "/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
		if (verbose)
			fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), homepath.c_str());
		if (file_test_open(homepath))
			return homepath;
	}

	std::string prefixpath = PREFIX "/share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
	if (verbose)
		fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), prefixpath.c_str());
	if (file_test_open(prefixpath))
		return prefixpath;

	std::string relbinarypath = proc_self_dirname() + "../share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
	if (verbose)
		fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), relbinarypath.c_str());
	if (file_test_open(relbinarypath))
		return relbinarypath;

	return "";
}

