
#include "jsclassregistrar.h"

namespace pappso
{
std::unordered_map<NamespaceClassnamePairAsKey,
                   RegisterFunc,
                   NamespaceClassnameAsKeyHash,
                   AreNamespaceClassnamePairsEqual> &
getNameSpaceClassNameJsConstructorRegistrarMap()
{
  static std::unordered_map<NamespaceClassnamePairAsKey,
                            RegisterFunc,
                            NamespaceClassnameAsKeyHash,
                            AreNamespaceClassnamePairsEqual>
    map;
  return map;
}


void
registerJsConstructorForEachClassInRegistrarMap(QJSEngine *engine)
{
  // qDebug() << "Registering the constructor of the classes marked for JS.";

  // qsizetype count = getNameSpaceClassNameJsConstructorRegistrarMap().size();
  // qDebug() << "Size of the map: count" << count;

  // Remember, the registrar map is actually a map of map:

  // Key type: pair of namespace and class name
  // using NamespaceClassnamePairAsKey = std::pair<QString, QString>;
  // using RegisterFunc                = std::function<void(QJSEngine *)>;
  //
  // std::unordered_map<NamespaceClassnamePairAsKey,
  //                    RegisterFunc,
  //                    NsClassKeyHash,
  //                    AreNamespaceClassnamePairAsKeyEqual>

  for(const auto &entry : getNameSpaceClassNameJsConstructorRegistrarMap())
    {
      // qDebug() << "Now registering" << entry.first.first << "-" << entry.first.second;
      entry.second(engine);
    }
}


// Note that name_space can be compounded: MsXpS::libXpertMass, for class name Formula, for example.
void
registerJsConstructorForNameSpaceClassNameInRegistrarMap(const QString &name_space,
                                                         const QString &class_name,
                                                         QJSEngine *engine)
{
  // Remember, the registrar map is actually a map of map:

  // Key type: pair of namespace and class name
  // using NamespaceClassnamePairAsKey = std::pair<QString, QString>;
  // using RegisterFunc                = std::function<void(QJSEngine *)>;
  //
  // std::unordered_map<NamespaceClassnamePairAsKey,
  //                    RegisterFunc,
  //                    NsClassKeyHash,
  //                    AreNamespaceClassnamePairAsKeyEqual>

  // So, first look for a pair<NamespaceClassnamePairAsKey, RegisterFunc>
  // having key = {name_space, class_name}, that is, a std::pair<QString,
  // QString>. Once we get that map item, run the second member of the
  // outer map item which actually runs the functor.
  auto it = getNameSpaceClassNameJsConstructorRegistrarMap().find({name_space, class_name});
  if(it != getNameSpaceClassNameJsConstructorRegistrarMap().end())
    it->second(engine);
  else
    qWarning().noquote() << "No JS constructor registered for namespace" << name_space
                         << "and class name" << class_name;
}

} // namespace pappso
