#pragma once

#include <balancer/kernel/helpers/default_instance.h>

#include <util/datetime/base.h>

namespace NSrvKernel {

class IThreadTimeArbiter;

class TThreadTimeManager : public TWithMutableInstance<TThreadTimeManager> {
public:
    TThreadTimeManager() noexcept;
    ~TThreadTimeManager();

    void SleepUntil(TInstant tp) const noexcept;

    void Sleep(TDuration dur) const noexcept {
        SleepUntil(this->ToDeadline(dur));
    }

    TInstant Now() const noexcept;

    TInstant ToDeadline(TDuration dur) const noexcept {
        return dur.ToDeadLine(this->Now());
    }

    void EnableTesting() noexcept {
        Testing_ = true;
    }

public:
    class TMockGuard {
    public:
        TMockGuard(THolder<IThreadTimeArbiter> mock) noexcept;
        ~TMockGuard();

    private:
        THolder<IThreadTimeArbiter> PrevArbiter_;
    };

private:
    void VerifyTesting() noexcept {
        Y_VERIFY(Testing_, "Changing the guts of TFileManager in production code is forbidden.\n"
                           "Did you forget to call EnableTesting()?");
    }

private:
    THolder<IThreadTimeArbiter> TimeArbiter_;
    bool Testing_ = false;
};

}  // namespace NSrvKernel
