#pragma once
#ifndef ANSLIBSLOADER_H
#define ANSLIBSLOADER_H

// ============================================================================
// ANSLibsLoader — Centralized dynamic library loader for ANSCENTER
//
// Consolidates all runtime DLL loading:
//   - ONNX Runtime (via EPLoader)
//   - TensorRT / cuDNN / CUDA (via NvDynLoader)
//   - OpenCV (via CvLoader)
//   - OpenVINO + TBB (via OvLoader)
//
// USAGE
// -----
//   // At application startup:
//   ANSCENTER::ANSLibsLoader::Initialize();
//
//   // At application exit (after all engine objects are destroyed):
//   ANSCENTER::ANSLibsLoader::Shutdown();
//
// EXPORT MACRO
// ------------
//   ANSLIBS_API replaces both ANSCORE_API and ENGINE_API for loader classes.
//   Define ANSLIBSLOADER_EXPORTS when building ANSLibsLoader.dll.
//   All other projects importing from ANSLibsLoader get __declspec(dllimport).
// ============================================================================

#ifdef _WIN32
#  ifdef ANSLIBSLOADER_EXPORTS
#    define ANSLIBS_API __declspec(dllexport)
#  else
#    define ANSLIBS_API __declspec(dllimport)
#  endif
#else
#  define ANSLIBS_API
#endif

#include "ANSLicense.h"   // for ANSCENTER::EngineType enum
#include <string>

namespace ANSCENTER {

    class ANSLIBS_API ANSLibsLoader
    {
    public:
        // ── Platform defaults ────────────────────────────────────────────────
#ifdef _WIN32
        static constexpr const char* DEFAULT_SHARED_DIR =
            "C:\\ProgramData\\ANSCENTER\\Shared";
#else
        static constexpr const char* DEFAULT_SHARED_DIR =
            "/opt/anscenter/shared";
#endif

        // ── Master initialization ────────────────────────────────────────────
        /// Calls all sub-loaders in the correct order:
        ///   1. Injects shared_dir into DLL search path
        ///   2. CvLoader   — pre-loads OpenCV
        ///   3. OvLoader   — pre-loads OpenVINO + TBB
        ///   4. NvDynLoader — loads TRT / cuDNN / CUDA (if NVIDIA)
        ///   5. EPLoader   — loads ONNX Runtime with selected EP
        ///
        /// Thread-safe. Subsequent calls are no-ops.
        static void Initialize(
            const std::string& shared_dir = DEFAULT_SHARED_DIR,
            EngineType preferred = EngineType::AUTO_DETECT);

        // ── Master shutdown ──────────────────────────────────────────────────
        /// Shuts down all sub-loaders in reverse order.
        /// Must be called AFTER all engine/session objects are destroyed.
        /// Safe to call multiple times.
        static void Shutdown();

        // ── Status ───────────────────────────────────────────────────────────
        [[nodiscard]] static bool IsInitialized();

        // ── Non-copyable / non-movable ───────────────────────────────────────
        ANSLibsLoader() = delete;
        ANSLibsLoader(const ANSLibsLoader&) = delete;
        ANSLibsLoader& operator=(const ANSLibsLoader&) = delete;

    private:
        static bool s_initialized;
    };

} // namespace ANSCENTER

#endif // ANSLIBSLOADER_H
