#pragma once

#include "fl/stl/flat_map.h"
#include "fl/stl/mutex.h"
#include "fl/stl/noexcept.h"
namespace fl {

/**
 * Thread-safe ID tracker that maps void* pointers to unique integer IDs.
 *
 * Features:
 * - Auto-incrementing ID counter for new entries
 * - Thread-safe operations with mutex protection
 * - Instantiable class - create as many trackers as needed
 * - Support for removal of tracked pointers
 *
 * Usage:
 *   IdTracker tracker;  // Create instance
 *   int id = tracker.getOrCreateId(ptr);
 *   bool found = tracker.getId(ptr, &id);
 *   tracker.removeId(ptr);
 *
 * For singleton behavior, wrap in your own singleton:
 *   static IdTracker& getGlobalTracker() {
 *       static IdTracker instance;
 *       return instance;
 *   }
 */
class IdTracker {
public:
    /**
     * Default constructor - creates a new ID tracker instance
     */
    IdTracker() FL_NOEXCEPT = default;

    /**
     * Get existing ID for pointer, or create a new one if not found.
     * Thread-safe.
     *
     * @param ptr Pointer to track
     * @return Unique integer ID for this pointer
     */
    int getOrCreateId(void* ptr) FL_NOEXCEPT;

    /**
     * Get existing ID for pointer without creating a new one.
     * Thread-safe.
     *
     * @param ptr Pointer to look up
     * @param outId Pointer to store the ID if found
     * @return true if ID was found, false if pointer not tracked
     */
    bool getId(void* ptr, int* outId) FL_NOEXCEPT;

    /**
     * Remove tracking for a pointer.
     * Thread-safe.
     *
     * @param ptr Pointer to stop tracking
     * @return true if pointer was being tracked and removed, false if not found
     */
    bool removeId(void* ptr) FL_NOEXCEPT;

    /**
     * Get the current number of tracked pointers.
     * Thread-safe.
     *
     * @return Number of currently tracked pointers
     */
    size_t size() FL_NOEXCEPT;

    /**
     * Clear all tracked pointers and reset ID counter.
     * Thread-safe.
     */
    void clear() FL_NOEXCEPT;

    // Non-copyable and non-movable for thread safety
    // (Each instance should have its own independent state)
    IdTracker(const IdTracker&) FL_NOEXCEPT = delete;
    IdTracker& operator=(const IdTracker&) FL_NOEXCEPT = delete;
    IdTracker(IdTracker&&) FL_NOEXCEPT = delete;
    IdTracker& operator=(IdTracker&&) FL_NOEXCEPT = delete;

private:

    // Thread synchronization
    mutable fl::mutex mMutex;

    // ID mapping and counter
    fl::flat_map<void*, int> mPointerToId;
    int mNextId = 0;  // Start IDs at 0 to match StripIdMap behavior
};

} // namespace fl
