//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include <armnn/backends/DynamicBackend.hpp>
#include <backendsCommon/DynamicBackendUtils.hpp>

namespace armnn
{

DynamicBackend::DynamicBackend(const void* sharedObjectHandle)
    : m_BackendIdFunction(nullptr)
    , m_BackendVersionFunction(nullptr)
    , m_BackendFactoryFunction(nullptr)
    , m_Handle(const_cast<void*>(sharedObjectHandle), &DynamicBackendUtils::CloseHandle)
{
    if (m_Handle == nullptr)
    {
        throw InvalidArgumentException("Cannot create a DynamicBackend object from an invalid shared object handle");
    }

    // These calls will throw in case of error
    m_BackendIdFunction      = SetFunctionPointer<IdFunctionType>("GetBackendId");
    m_BackendVersionFunction = SetFunctionPointer<VersionFunctionType>("GetVersion");
    m_BackendFactoryFunction = SetFunctionPointer<FactoryFunctionType>("BackendFactory");

    // Check that the backend is compatible with the current Backend API
    BackendId backendId = GetBackendId();
    BackendVersion backendVersion = GetBackendVersion();
    if (!DynamicBackendUtils::IsBackendCompatible(backendVersion))
    {
        throw RuntimeException(boost::str(boost::format("The dynamic backend %1% (version %2%) is not compatible"
                                                        "with the current Backend API (vesion %3%)")
                                          % backendId
                                          % backendVersion
                                          % IBackendInternal::GetApiVersion()));
    }
}

BackendId DynamicBackend::GetBackendId()
{
    if (m_BackendIdFunction == nullptr)
    {
        throw RuntimeException("GetBackendId error: invalid function pointer");
    }

    const char* backendId = m_BackendIdFunction();
    if (backendId == nullptr)
    {
        throw RuntimeException("GetBackendId error: invalid backend id");
    }

    return BackendId(backendId);
}

BackendVersion DynamicBackend::GetBackendVersion()
{
    if (m_BackendVersionFunction == nullptr)
    {
        throw RuntimeException("GetBackendVersion error: invalid function pointer");
    }

    uint32_t major = 0;
    uint32_t minor = 0;
    m_BackendVersionFunction(&major, &minor);

    return BackendVersion{ major, minor };
}

IBackendInternalUniquePtr DynamicBackend::GetBackend()
{
    // This call throws in case of error
    return CreateBackend();
}

BackendRegistry::FactoryFunction DynamicBackend::GetFactoryFunction()
{
    if (m_BackendFactoryFunction == nullptr)
    {
        throw RuntimeException("GetFactoryFunction error: invalid function pointer");
    }

    return [this]() -> IBackendInternalUniquePtr
    {
        // This call throws in case of error
        return CreateBackend();
    };
}

template<typename BackendFunctionType>
BackendFunctionType DynamicBackend::SetFunctionPointer(const std::string& backendFunctionName)
{
    if (m_Handle == nullptr)
    {
        throw RuntimeException("SetFunctionPointer error: invalid shared object handle");
    }

    if (backendFunctionName.empty())
    {
        throw RuntimeException("SetFunctionPointer error: backend function name must not be empty");
    }

    // This call will throw in case of error
    auto functionPointer = DynamicBackendUtils::GetEntryPoint<BackendFunctionType>(m_Handle.get(),
                                                                                   backendFunctionName.c_str());
    if (!functionPointer)
    {
        throw RuntimeException("SetFunctionPointer error: invalid backend function pointer returned");
    }

    return functionPointer;
}

IBackendInternalUniquePtr DynamicBackend::CreateBackend()
{
    if (m_BackendFactoryFunction == nullptr)
    {
        throw RuntimeException("CreateBackend error: invalid function pointer");
    }

    auto backendPointer = reinterpret_cast<IBackendInternal*>(m_BackendFactoryFunction());
    if (backendPointer == nullptr)
    {
        throw RuntimeException("CreateBackend error: backend instance must not be null");
    }

    return std::unique_ptr<IBackendInternal>(backendPointer);
}

} // namespace armnn
