#pragma once

#include "resolver_config.h"
#include "resolver_face.h"

#include <balancer/kernel/fs/shared_files.h>
#include <balancer/kernel/fs/shared_file_rereader.h>

class TContExecutor;

namespace NSrvKernel {

class TSharedFiles;
class TThreadedQueue;

namespace NDns {

class TAsyncResolver;
class TContResolver;

class IModeChecker {
public:
    enum class ECurrentMode {
        NotSet,
        Async,
        Threaded
    };

    virtual ~IModeChecker() = default;
    virtual ECurrentMode GetCurrentMode() = 0;
};

//! For use in single thread only
class TItsSwitch final : public IResolver {
public:
    TItsSwitch(THolder<IResolver>&& async, THolder<IResolver>&& threaded,
               THolder<IModeChecker>&& checker, const TResolverConfig& config);
    TItsSwitch(const TItsSwitch&) = delete;
    TItsSwitch(TItsSwitch&&) = delete;
    TItsSwitch& operator=(const TItsSwitch&) = delete;
    TItsSwitch& operator=(TItsSwitch&&) = delete;
    ~TItsSwitch() override;

private:
    TErrorOr<TSockAddrInfo> DoResolve(const TResolveInfo& info, bool onlyCache, TInstant deadline) override;
    void DoResetCache() override;

    void SetMode() noexcept;

private:
    THolder<IResolver> AsyncResolver_;
    THolder<IResolver> Resolver_;
    THolder<IModeChecker> Checker_;
    IResolver* Current_ = nullptr;
};

THolder<TItsSwitch> MakeItsSwitchResolver(TContExecutor* executor, TStatsCounters& counters,
        TSharedFiles* sharedFiles, const TResolverConfig& config, TThreadedQueue* queue);

}}