#ifndef FWCore_PluginManager_CacheParser_h
#define FWCore_PluginManager_CacheParser_h
// -*- C++ -*-
//
// Package:     PluginManager
// Class  :     CacheParser
//
/**\class CacheParser CacheParser.h FWCore/PluginManager/interface/CacheParser.h

 Description: Parses the cache information about which plugins are in which libraries

 Usage:
    The format expected is line oriented, with each lying containing

    <file name> <plugin name> <plugin type>

If a space exists in either of these three fields, it will be replaced with a %, E.g.
    /local/lib/pluginFoo.so Widget Fabulous%Bar%Stuff

*/
//
// Original Author:  Chris Jones
//         Created:  Wed Apr  4 14:30:51 EDT 2007
//

// system include files
#include <filesystem>
#include <iosfwd>
#include <string>
#include <map>
#include <vector>
// user include files
#include "FWCore/PluginManager/interface/PluginInfo.h"

// forward declarations
class TestCacheParser;

namespace edmplugin {
  class CacheParser {
  public:
    typedef std::map<std::string, std::vector<PluginInfo> > CategoryToInfos;
    typedef std::pair<std::string, std::string> NameAndType;
    typedef std::vector<NameAndType> NameAndTypes;
    typedef std::map<std::filesystem::path, NameAndTypes> LoadableToPlugins;

    CacheParser(const CacheParser&) = delete;                   // stop default
    const CacheParser& operator=(const CacheParser&) = delete;  // stop default

    // ---------- const member functions ---------------------

    // ---------- static member functions --------------------

    // ---------- member functions ---------------------------
    /**The std::vector<PluginInfo>'s in CategoryToInfos are guaranteed to be ordered by
        PluginInfo.name_ where identical names are ordered by the order they are passed to read.
        In this way multiple calls to read for different directories will preserve the ordering
        */
    static void read(std::istream&, const std::filesystem::path& iDirectory, CategoryToInfos& oOut);
    static void write(const CategoryToInfos&, std::ostream&);

    static void read(std::istream&, LoadableToPlugins& oOut);
    static void write(LoadableToPlugins& iIn, std::ostream&);

  private:
    //for testing
    friend class ::TestCacheParser;

    static bool readline(std::istream& iIn,
                         const std::filesystem::path& iDirectory,
                         unsigned long iRecordNumber,
                         PluginInfo& oInfo,
                         std::string& oPluginType);
    static std::string& replaceSpaces(std::string& io);
    static std::string& restoreSpaces(std::string& io);

    // ---------- member data --------------------------------
  };

}  // namespace edmplugin
#endif
