// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// 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.

#ifndef SharedLibrary_hpp
#define SharedLibrary_hpp

#if defined(_WIN32)
	#include <Windows.h>
#else
	#include <dlfcn.h>
#endif

#include <string>

void *getLibraryHandle(const char *path);
void *loadLibrary(const char *path);
void freeLibrary(void *library);
void *getProcAddress(void *library, const char *name);

template<int n>
void *loadLibrary(const std::string &libraryDirectory, const char *(&names)[n], const char *mustContainSymbol = nullptr)
{
	for(const char *libraryName : names)
	{
		std::string libraryPath = libraryDirectory + libraryName;
		void *library = getLibraryHandle(libraryPath.c_str());

		if(library)
		{
			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
			{
				return library;
			}

			freeLibrary(library);
		}
	}

	for(const char *libraryName : names)
	{
		std::string libraryPath = libraryDirectory + libraryName;
		void *library = loadLibrary(libraryPath.c_str());

		if(library)
		{
			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
			{
				return library;
			}

			freeLibrary(library);
		}
	}

	return nullptr;
}

#if defined(_WIN32)
	inline void *loadLibrary(const char *path)
	{
		return (void*)LoadLibrary(path);
	}

	inline void *getLibraryHandle(const char *path)
	{
		HMODULE module = NULL;
		GetModuleHandleEx(0, path, &module);
		return (void*)module;
	}

	inline void freeLibrary(void *library)
	{
		FreeLibrary((HMODULE)library);
	}

	inline void *getProcAddress(void *library, const char *name)
	{
		return (void*)GetProcAddress((HMODULE)library, name);
	}

	inline std::string getModuleDirectory()
	{
		static int dummy_symbol = 0;

		HMODULE module = NULL;
		GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&dummy_symbol, &module);

		char filename[1024];
		if(module && (GetModuleFileName(module, filename, sizeof(filename)) != 0))
		{
			std::string directory(filename);
			return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
		}
		else
		{
			return "";
		}
	}
#else
	inline void *loadLibrary(const char *path)
	{
		return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
	}

	inline void *getLibraryHandle(const char *path)
	{
		#ifdef __ANDROID__
			// bionic doesn't support RTLD_NOLOAD before L
			return dlopen(path, RTLD_NOW | RTLD_LOCAL);
		#else
			void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD | RTLD_LOCAL);

			if(resident)
			{
				return dlopen(path, RTLD_LAZY | RTLD_LOCAL);   // Increment reference count
			}

			return nullptr;
		#endif
	}

	inline void freeLibrary(void *library)
	{
		if(library)
		{
			dlclose(library);
		}
	}

	inline void *getProcAddress(void *library, const char *name)
	{
		void *symbol = dlsym(library, name);

		if(!symbol)
		{
			const char *reason = dlerror();   // Silence the error
			(void)reason;
		}

		return symbol;
	}

	inline std::string getModuleDirectory()
	{
		static int dummy_symbol = 0;

		Dl_info dl_info;
		if(dladdr(&dummy_symbol, &dl_info) != 0)
		{
			std::string directory(dl_info.dli_fname);
			return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
		}
		else
		{
			return "";
		}
	}
#endif

#endif   // SharedLibrary_hpp
