#pragma once

#include <library/cpp/http/misc/httpreqdata.h>
#include <util/generic/string.h>
#include <util/generic/set.h>
#include <library/cpp/cgiparam/cgiparam.h>
#include <saas/indexerproxy/adapters/interface_adapter.h>

class TRequestOptions: public IRequestOptions {
public:
    TRequestOptions();
    void Parse(const TServerRequestData& rd);

    bool IsTrace() const override {
        return Trace;
    }
    bool IsDeferredMessage() const override {
        return false;
    }
    bool GetVerboseLogging() const override {
        return VerboseLogging;
    }
    bool GetWaitReply() const override {
        return WaitReply;
    }
    virtual bool IsInstantReply() const override {
        return InstantReply;
    }
    bool IsRealtime() const override {
        return Realtime;
    }
    bool HasTimeout() const override {
        return Timeout != TDuration::Max();
    }
    ui64 GetSizeLimit() const override {
        return SizeLimit;
    }
    const TString& GetAuthCookie() const override {
        return AuthCookie;
    }
    const TString& GetSource() const override {
        return Source;
    }
    TDuration GetTimeout() const override {
        return Timeout;
    }

    bool GetBypassDistributor() const override {
        return BypassDistributor;
    }
    bool QueueDisabled() const override {
        return DisableQueue;
    }

    bool BackendAllowed(const TString& backend) const override {
        if (AllowedBackends.empty())
            return true;
        return AllowedBackends.contains(backend);
    }

    bool GetHasRealtimeFlag() const override {
        return HasRealtimeFlag;
    }

    virtual TDuration GetIndexSleep() const override {
        return IndexSleep;
    }

private:
    inline void ParseTrace(const TServerRequestData& rd);
    inline void ParseVerboseLogging(const TServerRequestData& rd);
    inline void ParseWaitReply(const TServerRequestData& rd);
    inline void ParseRealtime(const TServerRequestData& rd);
    inline void ParseTimeout(const TServerRequestData& rd);
    inline void ParseAllowedBackends(const TServerRequestData& rd);
    inline void ParseAuthCookie(const TServerRequestData& rd);
    inline void ParseSource(const TServerRequestData& rd);
    inline void ParseBypassDistributor(const TServerRequestData& rd);
    inline void ParseSizeLimit(const TServerRequestData& rd);
    inline void ParseIndexSleep(const TServerRequestData& rd);
    inline void ParseInstantReply(const TServerRequestData& rd);

private:
    bool Trace = false;
    bool VerboseLogging = false;
    bool WaitReply = true;
    bool Realtime = true;
    bool HasRealtimeFlag = false;
    bool BypassDistributor = false;
    bool DisableQueue = false;
    bool InstantReply = false;
    ui64 SizeLimit = 0;
    TString AuthCookie;
    TString Source;
    TDuration Timeout = TDuration::Max();
    TSet<TString> AllowedBackends;
    TDuration IndexSleep;

    template <class T>
    bool ReadCgiParam(const TServerRequestData& rd, const TString& paramName, T& value) {
        if (rd.CgiParam.Has(paramName)) {
            T valueResult;
            if (TryFromString<T>(rd.CgiParam.Get(paramName), valueResult)) {
                value = valueResult;
                return true;
            }
        }
        return false;
    }

};
