#pragma once

#include <robot/jupiter/library/rtdoc/merger/doc_hit_patcher.h>
#include <robot/jupiter/library/rtdoc/merger/wad_patcher.h>
#include <util/generic/buffer.h>
#include <util/generic/hash.h>

namespace NFusion {
    class TWadPatcher : public NRtDoc::IWadPatcher {
    private:
        THashMap<NDoom::TWadLumpId, NRtDoc::IDocHitPatcher::TPtr> DocPatchersById_;
        TVector<NRtDoc::IDocHitPatcher::TPtr> DocPatchers_;
        TBuffer Buffer_ = TBuffer(1 << 16); //this class is single-threaded in use
        bool Created_ = false;

    public:
        void Add(const NRtDoc::IDocHitPatcher::TPtr& patcher) {
            Y_ENSURE(!Created_);
            auto lumpIds = patcher->GetApplicableLumpIds();
            for (auto lumpId : lumpIds) {
                DocPatchersById_[lumpId] = patcher;
            }
            DocPatchers_.emplace_back(patcher);
        }

        void Init() {
            Y_ENSURE(!Created_);
            Created_ = true;
        }

        void Reset(const NDoom::IWad* wad) override {
            for(const auto& patcher : DocPatchers_) {
                patcher->Reset(wad);
            }
        }

        TArrayRef<const char> ProcessDoc(ui32 docId, NDoom::TWadLumpId id, const TArrayRef<const char>& source) override {
            auto p = DocPatchersById_.find(id);
            if (p == DocPatchersById_.end()) {
                return source;
            }

            return p->second->ProcessLump(docId, id, source, Buffer_);
        }
    };
}
