#pragma once

#include <saas/deploy_manager/storage/abstract.h>
#include <saas/library/sharding/sharding.h>
#include <library/cpp/object_factory/object_factory.h>
#include <library/cpp/json/writer/json_value.h>

namespace NRTYDeploy {

    class TNodesStructure;

    class TFileContentGenerator {
    public:
        typedef NObjectFactory::TObjectFactory<TFileContentGenerator, TString> TFactory;
        typedef TAtomicSharedPtr<TFileContentGenerator> TPtr;

        struct TContext {
            TContext();
            bool DeserializeFromJson(const NJson::TJsonValue& json);
            void SerializeToJson(NJson::TJsonValue& json) const;
            NSaas::TSlotInfo SlotInfo;
            bool NoAnyPatch;
            TSet<TString> ForceServices;
            mutable TMap<TString, TNodesStructure> ForceStructures;
        };

    public:
        virtual ~TFileContentGenerator() {}
        virtual TString GetType() const = 0;
        virtual bool GetContent(TString& result, const ICommonData& common, const TContext& context) const = 0;
        virtual TString GetRename(const TContext& context) const = 0;
        virtual void SetLastVersion();
        static TPtr Deserialize(const NJson::TJsonValue& json);
        static TPtr Deserialize(const ICommonData& common, TContext& context, const TString& root, const TString& filename, i64 version);
        virtual void Serialize(NJson::TJsonValue& json) const;
        bool SerializeWithContext(TString& result, const TContext& context) const;
        virtual void DoDeserialize(const NJson::TJsonValue& json);
        virtual bool GetContentHash(TString& result, const ICommonData& common, const TContext& context) const;

        static TPtr Create(const TFsPath& path, const ICommonData& common, const NSaas::TSlotInfo& slotInfo, i64 version = -1);
        static ui32 AddGenerators(TVector<TPtr>& list, const ICommonData& common, const TFsPath& path, const TString& filenamePrefix, const NSaas::TSlotInfo& slotInfo);

        static const TString ServiceNameMacros;
    };

}
