#pragma once

/*
	PluginFramework
	by John Ryland
	Copyright (c) 2023
*/

////////////////////////////////////////////////////////////////////////////////////
//	Library

#include <memory>
#include <string>

namespace PluginFramework {

class Library;
using LibraryPtr = std::unique_ptr<Library>;

class Library
{
    struct Handle;
public:
    // These should be constructed by calling LoadLibrary (Handle is deliberately private)
    Library(const char* fileName, Handle osHandle);

    // Unloads the library if it was loaded
    ~Library();

    // Provide the filename of the library to load. Returned value is able to be null
    static LibraryPtr Load(const char* libraryFileName);

    bool Loaded() const;

    std::string FileName() const;

    // Look up address of a function from the string of the exported symbol name in the library
    void* GetFunctionAddress(const char* functionName) const;

private:
    friend class Plugin;
    void Unload();

    // We are using the 'passkey idiom' so Load can use std::make_unique
    struct Handle
    {
        // Operating specific handle to the library
        void* mOSHandle;
    };
    Handle       mLibraryHandle;
    std::string  mLibraryFileName;
};

} // PluginFramework namespace
