#pragma once

#include "async_entry_i.h"

#include <library/cpp/coroutine/engine/events.h>


namespace NSrvKernel::NDns {


class TEntry : public IEntry {
public:
    TEntry(TContExecutor* e, TDuration recordTtl);

    EResolveState GetState() const noexcept override { return State_; }
    const TSockAddrInfo& GetAddrInfo() const noexcept override { return Addrs_; }
    bool HasValidResult() const noexcept override { return !Addrs_.Addresses.empty(); }
    bool IsExpired(TDuration ttl) const noexcept override { return ResolveTimestamp_ + ttl < TInstant::Now(); }
    bool HasRequestsInProgress() const noexcept override { return RequestsInProgress_; }

    void AddRequestInProgress() noexcept override;
    bool SetFailedIfDone() noexcept override;

    void AddResult(TSockAddr&& result) noexcept override;

    bool WaitD(TInstant deadline, int& waitResultCode) noexcept override;

    void SetInProgress() noexcept override;

    bool ResetFailedIfExpired(TDuration ttl) noexcept override;

private:
    TSockAddrInfo Addrs_;
    TInstant ResolveTimestamp_;
    const TDuration RecordTtl_; //!< result is dropped only if TTL expired AND a new one is obtained
    EResolveState State_;
    TContSimpleEvent ResolvedEvent_;
    uint64_t RequestsInProgress_ = 0;
};


class TEntryBuilder : public IEntryBuilder {
public:
    TEntryHolder GetNewEntry(TContExecutor* e, TDuration ttl) const override;
};

}