#pragma once

#include <kernel/doom/wad/wad_lump_id.h>
#include <robot/jupiter/library/rtdoc/merger/wad_merger.h>
#include <saas/rtyserver_jupi/library/extbuilder/bundle_model.h>

namespace NRtDoc {
    class TDocIdMap;

    class TArcMerger : public IWadMerger {
    public:
        TArcMerger() = default;
        TArcMerger(const TString& fileName, TString mappingFileName);

        void Init(const TString& fileName) final;

        void Add(const TString& wadPath, THolder<TDocIdMap>, IWadPatcher::TPtr, const TString& name, bool /*isDelta*/) final;

        bool Empty() const final;

        void CheckMergeable() final;

        void Finish() final;

    private:
        struct TChunk {
            TString Path;
            THolder<TDocIdMap> DocIdMap;

            TChunk() = default;
            TChunk(TString path, THolder<TDocIdMap> docIdMap)
                : Path(std::move(path))
                , DocIdMap(std::move(docIdMap))
            {
            }
        };

        TVector<TChunk> Chunks;
        TString FileName;
        TString MappingFileName;
    };

    extern const TStringBuf ARC_SUFFIX;
    extern const TStringBuf ARC_WAD_SUFFIX;

    void ConvertArcToWad(const TString& arcPath, const TString& wadPath, NDoom::TWadLumpId);
}

namespace NFusion {
    class TArcExtension : public ICmdExtensions {
    public:
        NRtDoc::IWadMerger::TPtr CreateWadCustomMerger() final {
            return MakeIntrusive<NRtDoc::TArcMerger>();
        }

        TString ConstructFileName(const TString& outputPrefix) const final {
            return outputPrefix + NRtDoc::ARC_SUFFIX;
        }
    };

    class TArcWadExtension : public ICmdExtensions {
    public:
        TArcWadExtension(TString oldName, NDoom::TWadLumpId lumpId)
            : OldName(std::move(oldName))
            , LumpId(lumpId)
        {
        }

        void Init(TJupiterCmd& cmd, const TBundleVersion&) final {
            OutputPrefix = cmd.OutputPrefix;
        }

        void PreprocessInputs(const NRtDoc::IBuilderInputs&) final;

        TString ConstructFileName(const TString& outputPrefix) const final {
            return outputPrefix + NRtDoc::ARC_WAD_SUFFIX;
        }
    private:
        const TString OldName;
        const NDoom::TWadLumpId LumpId;
        TString OutputPrefix;
    };

    class TChunkedArcWadExtension : public ICmdExtensions {
    public:
        void Init(TJupiterCmd& cmd, const TBundleVersion&) final {
            OutputPrefix = cmd.OutputPrefix;
        }

        void PreprocessInputs(const NRtDoc::IBuilderInputs&) final;

    private:
        TString OutputPrefix;
    };

}

