#pragma once

#include "effecters.hpp"

#include <stdint.h>

#include <filesystem>
#include <fstream>
#include <functional>
#include <map>
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <string>
#include <vector>
#include <xyz/openbmc_project/Common/error.hpp>

#include "libpldm/platform.h"

using namespace phosphor::logging;
using InternalFailure =
    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
namespace fs = std::filesystem;

namespace pldm
{

namespace responder
{

namespace pdr
{

using Type = uint8_t;
using Json = nlohmann::json;
using RecordHandle = uint32_t;
using Entry = std::vector<uint8_t>;
using Pdr = std::vector<Entry>;

/** @class Repo
 *
 *  @brief Abstract class describing the interface API to the PDR repository
 *
 *  Concrete implementations of this must handle storing and addressing the
 *  PDR entries by a "record handle", which can be indices, offsets, etc.
 */
class Repo
{
  public:
    virtual ~Repo() = default;

    /** @brief Add a new entry to the PDR
     *
     *  @param[in] entry - new PDR entry
     */
    virtual void add(Entry&& entry) = 0;

    /** @brief Access PDR entry at inout record handle
     *
     *  @param[in] handle - record handle
     *
     *  @return Entry - PDR entry
     */
    virtual Entry at(RecordHandle handle) const = 0;

    /** @brief Get next available record handle for assignment
     *
     *  @return RecordHandle - PDR record handle
     */
    virtual RecordHandle getNextRecordHandle() const = 0;

    /** @brief Get record handle immediately suceeding the input record
     *         handle
     *
     *  @param[in] current - input record handle
     *
     *  @return RecordHandle - PDR record handle
     */
    virtual RecordHandle getNextRecordHandle(RecordHandle current) const = 0;

    /** @brief Get number of entries in the PDR
     *
     *  @return size_t - number of entries
     */
    virtual size_t numEntries() const = 0;

    /** @brief Check if PDR is empty
     *
     *  @return bool - true if PDR is empty, false otherwise
     */
    virtual bool empty() const = 0;

    /** @brief Empty the PDR
     */
    virtual void makeEmpty() = 0;
};

namespace internal
{

/** @brief Parse PDR JSON file and output Json object
 *
 *  @param[in] path - path of PDR JSON file
 *
 *  @return Json - Json object
 */
inline Json readJson(const std::string& path)
{
    std::ifstream jsonFile(path);
    if (!jsonFile.is_open())
    {
        log<level::INFO>("Error opening PDR JSON file",
                         entry("PATH=%s", path.c_str()));
        return {};
    }

    return Json::parse(jsonFile);
}

/** @class IndexedRepo
 *
 *  @brief Inherits and implements Repo
 *
 *  Stores the PDR as a vector of entries, and addresses PDR entries based on an
 *  incrementing record handle, starting at 1.
 */
class IndexedRepo : public Repo
{
  public:
    void add(Entry&& entry)
    {
        repo.emplace_back(std::move(entry));
    }

    Entry at(RecordHandle handle) const
    {
        if (!handle)
        {
            handle = 1;
        }
        return repo.at(handle - 1);
    }

    RecordHandle getNextRecordHandle() const
    {
        return repo.size() + 1;
    }

    RecordHandle getNextRecordHandle(RecordHandle current) const
    {
        if (current >= repo.size())
        {
            return 0;
        }
        if (!current)
        {
            current = 1;
        }
        return current + 1;
    }

    size_t numEntries() const
    {
        return repo.size();
    }

    bool empty() const
    {
        return repo.empty();
    }

    void makeEmpty()
    {
        repo.clear();
    }

  private:
    Pdr repo{};
};

/** @brief Parse PDR JSONs and build PDR repository
 *
 *  @param[in] dir - directory housing platform specific PDR JSON files
 *  @tparam[in] repo - instance of concrete implementation of Repo
 */
template <typename T>
void generate(const std::string& dir, T& repo)
{
    using namespace internal;
    // A map of PDR type to a lambda that handles creation of that PDR type.
    // The lambda essentially would parse the platform specific PDR JSONs to
    // generate the PDR structures. This function iterates through the map to
    // invoke all lambdas, so that all PDR types can be created.
    std::map<Type, std::function<void(const Json& json, T& repo)>> generators =
        {{PLDM_STATE_EFFECTER_PDR, [](const auto& json, T& repo) {
              static const std::vector<Json> emptyList{};
              static const Json empty{};
              auto entries = json.value("entries", emptyList);
              for (const auto& e : entries)
              {
                  size_t pdrSize = 0;
                  auto effecters = e.value("effecters", emptyList);
                  static const Json empty{};
                  for (const auto& effecter : effecters)
                  {
                      auto set = effecter.value("set", empty);
                      auto statesSize = set.value("size", 0);
                      if (!statesSize)
                      {
                          log<level::ERR>(
                              "Malformed PDR JSON - no state set info",
                              entry("TYPE=%d", PLDM_STATE_EFFECTER_PDR));
                          elog<InternalFailure>();
                      }
                      pdrSize += sizeof(state_effecter_possible_states) -
                                 sizeof(bitfield8_t) +
                                 (sizeof(bitfield8_t) * statesSize);
                  }
                  pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);

                  Entry pdrEntry{};
                  pdrEntry.resize(pdrSize);

                  pldm_state_effecter_pdr* pdr =
                      reinterpret_cast<pldm_state_effecter_pdr*>(
                          pdrEntry.data());
                  pdr->hdr.record_handle = repo.getNextRecordHandle();
                  pdr->hdr.version = 1;
                  pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
                  pdr->hdr.record_change_num = 0;
                  pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);

                  pdr->terminus_handle = 0;
                  pdr->effecter_id = effecter::nextId();
                  pdr->entity_type = e.value("type", 0);
                  pdr->entity_instance = e.value("instance", 0);
                  pdr->container_id = e.value("container", 0);
                  pdr->effecter_semantic_id = 0;
                  pdr->effecter_init = PLDM_NO_INIT;
                  pdr->has_description_pdr = false;
                  pdr->composite_effecter_count = effecters.size();

                  using namespace effecter::dbus_mapping;
                  Paths paths{};
                  uint8_t* start = pdrEntry.data() +
                                   sizeof(pldm_state_effecter_pdr) -
                                   sizeof(uint8_t);
                  for (const auto& effecter : effecters)
                  {
                      auto set = effecter.value("set", empty);
                      state_effecter_possible_states* possibleStates =
                          reinterpret_cast<state_effecter_possible_states*>(
                              start);
                      possibleStates->state_set_id = set.value("id", 0);
                      possibleStates->possible_states_size =
                          set.value("size", 0);

                      start += sizeof(possibleStates->state_set_id) +
                               sizeof(possibleStates->possible_states_size);
                      static const std::vector<uint8_t> emptyStates{};
                      auto states = set.value("states", emptyStates);
                      for (const auto& state : states)
                      {
                          auto index = state / 8;
                          auto bit = state - (index * 8);
                          bitfield8_t* bf =
                              reinterpret_cast<bitfield8_t*>(start + index);
                          bf->byte |= 1 << bit;
                      }
                      start += possibleStates->possible_states_size;

                      auto dbus = effecter.value("dbus", empty);
                      paths.emplace_back(std::move(dbus));
                  }
                  add(pdr->effecter_id, std::move(paths));
                  repo.add(std::move(pdrEntry));
              }
          }}};

    auto eraseLen = strlen(".json");
    Type pdrType{};
    for (const auto& dirEntry : fs::directory_iterator(dir))
    {
        try
        {
            auto json = readJson(dirEntry.path().string());
            if (!json.empty())
            {
                auto fileName = dirEntry.path().filename().string();
                fileName.erase(fileName.end() - eraseLen);
                pdrType = stoi(fileName);
                generators.at(pdrType)(json, repo);
            }
        }
        catch (const InternalFailure& e)
        {
        }
        catch (const std::exception& e)
        {
            log<level::ERR>("Failed parsing PDR JSON file",
                            entry("TYPE=%d", pdrType),
                            entry("ERROR=%s", e.what()));
            report<InternalFailure>();
        }
    }
}

} // namespace internal

/** @brief Build (if not built already) and retrieve PDR
 *
 *  @param[in] dir - directory housing platform specific PDR JSON files
 *
 *  @return Repo& - Reference to instance of pdr::Repo
 */
Repo& get(const std::string& dir);

} // namespace pdr
} // namespace responder
} // namespace pldm
