#pragma once

#include "bundle_model.h"

#include <robot/jupiter/library/rtdoc/merger/groupattrsmap.h>
#include <robot/jupiter/library/rtdoc/merger/wad_patcher.h>
#include <robot/jupiter/library/rtdoc/file/model/docidmap.h>

#include <util/folder/path.h>
#include <util/generic/ptr.h>

namespace NRtDoc {
    using namespace NDoom;

    //
    // IWadMerger adapter for host data: converts DocIdMaps into HostId maps
    //
    class TWadHostAdapter : public IWadMerger {
    public:
        TWadHostAdapter(IWadMerger::TPtr slave);

        ~TWadHostAdapter();


        virtual void Add(const TString& wadPath, THolder<TDocIdMap> docIdMap, IWadPatcher::TPtr wadPatcher, const TString& name, bool isDelta) override {
            Sources.emplace_back(wadPath, std::move(docIdMap), std::move(wadPatcher), name, isDelta);
        }

        virtual void CheckMergeable() override {
            Y_ENSURE(Slave);
            Slave->CheckMergeable();
        }

        virtual bool Empty() const override {
            return Sources.empty();
        }

        virtual void Finish() override {
            Y_ENSURE(Slave);
            BuildCategMap();
            for (auto&& s : Sources) {
                Y_ASSERT(s.CategMap);
                Slave->Add(s.WadPath, std::move(s.CategMap), std::move(s.WadPatcher), s.Name, s.IsDelta);
            }
            Slave->Finish();
        }

    public:
        virtual void Init(const TString& fileName) override;
        void BuildCategMap();

    private:
        struct TChunk {
            TString Name;
            TString WadPath;
            IWadPatcher::TPtr WadPatcher;
            THolder<TDocIdMap> CategMap; // source index uses categId (hostId) as a key
            THolder<TDocIdMap> DocIdMap; // DocIdMap here is used only to fill CategMap
            bool IsDelta;

            inline TChunk(const TString& wadPath, THolder<TDocIdMap>&& docIdMap, IWadPatcher::TPtr&& wadPatcher, const TString& name, bool isDelta)
                : Name(name)
                , WadPath(wadPath)
                , WadPatcher(std::move(wadPatcher))
                , DocIdMap(std::move(docIdMap))
                , IsDelta(isDelta)
            {
            }
        };

    private:
        IWadMerger::TPtr Slave;
        TCategMap::TPtr DestCategByDocId;
        TVector<TChunk> Sources;
    };

    // A helper that fuses some of THostAttrs items together ("GroupBy HostId");
    // It helps us make the intermediate Wad file smaller and avoid particular
    // limits of Offroad codecs (details: SPI-5433)
    NJupiter::TMercuryCmdPtr CreateReduceHostAttrsByDocId(const TFsPath& finalDirWithAa);
}
