/*!
    \file
    \copyright  (c) 2015 Jascha Wetzel. All rights reserved.
 */

#ifndef TFD_API_CLIENT_H
#define TFD_API_CLIENT_H

#include "api/interface_ids.h"

#include <cstdint>
#include <memory>
#include <string>

namespace tfd {
namespace api {

/*!
    Has to be called before any API function or class can be used.
    The file_path argument has to reference the TurbulenceFD shared library.
    On Windows that's any of the TFD_loader_* files.
 */
bool load_library(const std::string& file_path);

/*!
    Obtain server's API version.
 */
uint32_t get_server_version();

/*!
    Used to implement create_shared_instance.
    Don't call directly.
 */
void* create_instance(unsigned int);

/*!
    Any raw pointer returned by the API must be wrapped using this function
    to ensure the corresponding objects are properly released.
 */
template<class Iface>
inline std::shared_ptr<Iface>
wrap_raw_iface_pointer(Iface* ptr)
{
    if ( !ptr )
        return std::shared_ptr<Iface>();
    return std::shared_ptr<Iface>(
        ptr, [](Iface* ptr) {
            ptr->release();
        }
    );
}

/*!
    Tries to instantiate a class that corresponds to the given interface.
    Only some interfaces correspond to classes that can be instantiated directly by the API server (usually factory classes).
    For all other interfaces a nullptr will be returned.
 */
template<class Iface>
inline std::shared_ptr<Iface>
create_shared_instance()
{
    return wrap_raw_iface_pointer(
        static_cast<Iface*>(create_instance(InterfaceId<Iface>::id))
    );
}

} // namespace api
} // namespace tfd

#endif // TFD_API_CLIENT_H
