// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation

#pragma once

#include "configuration.hpp"
#include "dbus_interface.hpp"
#include "power_status_monitor.hpp"
#include "topology.hpp"

#include <boost/container/flat_map.hpp>
#include <nlohmann/json.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <string>

class EntityManager
{
  public:
    explicit EntityManager(
        std::shared_ptr<sdbusplus::asio::connection>& systemBus,
        boost::asio::io_context& io,
        const std::vector<std::filesystem::path>& configurationDirectories);

    // disable copy
    EntityManager(const EntityManager&) = delete;
    EntityManager& operator=(const EntityManager&) = delete;

    // disable move
    EntityManager(EntityManager&&) = delete;
    EntityManager& operator=(EntityManager&&) = delete;

    ~EntityManager() = default;

    std::shared_ptr<sdbusplus::asio::connection> systemBus;
    sdbusplus::asio::object_server objServer;
    std::shared_ptr<sdbusplus::asio::dbus_interface> entityIface;
    Configuration configuration;
    nlohmann::json lastJson;
    nlohmann::json systemConfiguration;
    Topology topology;
    boost::asio::io_context& io;

    dbus_interface::EMDBusInterface dbus_interface;

    power::PowerStatusMonitor powerStatus;

    void propertiesChangedCallback();
    void registerCallback(const std::string& path);
    void publishNewConfiguration(const size_t& instance, size_t count,
                                 boost::asio::steady_timer& timer,
                                 nlohmann::json newConfiguration);
    void postToDbus(const nlohmann::json& newConfiguration);
    void postBoardToDBus(const std::string& boardId,
                         const nlohmann::json& boardConfig,
                         std::map<std::string, std::string>& newBoards);
    void postExposesRecordsToDBus(
        nlohmann::json& item, size_t& exposesIndex,
        const std::string& boardNameOrig, std::string jsonPointerPath,
        const std::string& jsonPointerPathBoard, const std::string& boardPath,
        const std::string& boardType);

    // @returns false on error
    bool postConfigurationRecord(
        const std::string& name, nlohmann::json& config,
        const std::string& boardNameOrig, const std::string& itemType,
        const std::string& jsonPointerPath, const std::string& ifacePath);

    void pruneConfiguration(bool powerOff, const std::string& name,
                            const nlohmann::json& device);

    void handleCurrentConfigurationJson();

  private:
    std::unique_ptr<sdbusplus::bus::match_t> nameOwnerChangedMatch = nullptr;
    std::unique_ptr<sdbusplus::bus::match_t> interfacesAddedMatch = nullptr;
    std::unique_ptr<sdbusplus::bus::match_t> interfacesRemovedMatch = nullptr;

    bool scannedPowerOff = false;
    bool scannedPowerOn = false;

    bool propertiesChangedInProgress = false;
    boost::asio::steady_timer propertiesChangedTimer;
    size_t propertiesChangedInstance = 0;

    boost::container::flat_map<std::string, sdbusplus::bus::match_t>
        dbusMatches;

    void startRemovedTimer(boost::asio::steady_timer& timer,
                           nlohmann::json& systemConfiguration);
    void initFilters(const std::unordered_set<std::string>& probeInterfaces);
};
