#pragma once

#include "shared_file_rereader.h"
#include "shared_files.h"

#include <util/string/cast.h>
#include <util/string/strip.h>

namespace NSrvKernel {
    template <class T>
    class TWatchedState {
    public:
        T Default = T();

    public:
        TWatchedState() = default;

        TWatchedState(T defaultValue)
            : Default(std::move(defaultValue))
            , Current_(Default)
        {}

        TWatchedState(T defaultValue, TString fileName, TSharedFiles& sharedFiles)
            : TWatchedState(std::move(defaultValue))
        {
            if (fileName) {
                Reader_ = sharedFiles.FileReReader(fileName, TDuration::Seconds(1));
            }
        }

        TWatchedState(TWatchedState&& rhs) = default;
        TWatchedState& operator=(TWatchedState&& rhs) = default;

        template <class TParser>
        const T& Get(TParser&& parser) const {
            if (!Reader_.Empty()) {
                if (Reader_.Data().Id() != Data_.Id()) {
                    Data_ = Reader_.Data();
                    parser(Data_.Data(), Current_, Default);
                }
                return Current_;
            } else {
                return Default;
            }
        }

        const T& Get() const {
            return Get([](TStringBuf str, T& current, const T& deflt) {
                TryFromStringWithDefault(StripString(str), current, deflt);
            });
        }

    private:
        TSharedFileReReader Reader_;
        mutable TSharedFileReReader::TData Data_;
        mutable T Current_ = T();
    };
}
