#pragma once

#include "dbus_types.hpp"
#include "dbus_watcher.hpp"

#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>

#include <expected>
#include <filesystem>
#include <fstream>
#include <unordered_map>

namespace openpower
{
namespace pels
{

/**
 * @class DataInterface
 *
 * A base class for gathering data about the system for use
 * in PELs. Implemented this way to facilitate mocking.
 */
class DataInterfaceBase
{
  public:
    DataInterfaceBase() = default;
    virtual ~DataInterfaceBase() = default;
    DataInterfaceBase(const DataInterfaceBase&) = default;
    DataInterfaceBase& operator=(const DataInterfaceBase&) = default;
    DataInterfaceBase(DataInterfaceBase&&) = default;
    DataInterfaceBase& operator=(DataInterfaceBase&&) = default;

    /**
     * @brief Returns the machine Type/Model
     *
     * @return string - The machine Type/Model string
     */
    virtual std::string getMachineTypeModel() const = 0;

    /**
     * @brief Returns the machine serial number
     *
     * @return string - The machine serial number
     */
    virtual std::string getMachineSerialNumber() const = 0;

    /**
     * @brief Says if the system is managed by a hardware
     *        management console.
     * @return bool - If the system is HMC managed
     */
    virtual bool isHMCManaged() const
    {
        return _hmcManaged;
    }

    /**
     * @brief Says if the host is up and running
     *
     * @return bool - If the host is running
     */
    virtual bool isHostUp() const
    {
        return _hostUp;
    }

    using HostStateChangeFunc = std::function<void(bool)>;

    /**
     * @brief Register a callback function that will get
     *        called on all host on/off transitions.
     *
     * The void(bool) function will get passed the new
     * value of the host state.
     *
     * @param[in] name - The subscription name
     * @param[in] func - The function to run
     */
    void subscribeToHostStateChange(const std::string& name,
                                    HostStateChangeFunc func)
    {
        _hostChangeCallbacks[name] = func;
    }

    /**
     * @brief Unsubscribe from host state changes.
     *
     * @param[in] name - The subscription name
     */
    void unsubscribeFromHostStateChange(const std::string& name)
    {
        _hostChangeCallbacks.erase(name);
    }

    using FRUPresentFunc =
        std::function<void(const std::string& /* locationCode */)>;

    /**
     * @brief Register a callback function that will get
     *        called when certain FRUs become present.
     *
     * The void(std::string) function will get passed the
     * location code of the FRU.
     *
     * @param[in] name - The subscription name
     * @param[in] func - The function to run
     */
    void subscribeToFruPresent(const std::string& name, FRUPresentFunc func)
    {
        _fruPresentCallbacks[name] = std::move(func);
    }

    /**
     * @brief Returns the BMC firmware version
     *
     * @return std::string - The BMC version
     */
    virtual std::string getBMCFWVersion() const
    {
        return _bmcFWVersion;
    }

    /**
     * @brief Returns the server firmware version
     *
     * @return std::string - The server firmware version
     */
    virtual std::string getServerFWVersion() const
    {
        return _serverFWVersion;
    }

    /**
     * @brief Returns the BMC FW version ID
     *
     * @return std::string - The BMC FW version ID
     */
    virtual std::string getBMCFWVersionID() const
    {
        return _bmcFWVersionID;
    }

    /**
     * @brief Returns the process name given its PID.
     *
     * @param[in] pid - The PID value as a string
     *
     * @return std::optional<std::string> - The name, or std::nullopt
     */
    std::optional<std::string> getProcessName(const std::string& pid) const
    {
        namespace fs = std::filesystem;

        fs::path path{"/proc"};
        path /= fs::path{pid} / "exe";

        if (fs::exists(path))
        {
            return fs::read_symlink(path);
        }

        return std::nullopt;
    }

    /**
     * @brief Returns the time the system was running.
     *
     * @return std::optional<uint64_t> - The System uptime or std::nullopt
     */
    std::optional<uint64_t> getUptimeInSeconds() const
    {
        std::ifstream versionFile{"/proc/uptime"};
        std::string line{};

        std::getline(versionFile, line);
        auto pos = line.find(" ");
        if (pos == std::string::npos)
        {
            return std::nullopt;
        }

        uint64_t seconds = atol(line.substr(0, pos).c_str());
        if (seconds == 0)
        {
            return std::nullopt;
        }

        return seconds;
    }

    /**
     * @brief Returns the time the system was running.
     *
     * @param[in] seconds - The number of seconds the system has been running
     *
     * @return std::string - days/hours/minutes/seconds
     */
    std::string getBMCUptime(uint64_t seconds) const
    {
        time_t t(seconds);
        tm* p = gmtime(&t);

        std::string uptime =
            std::to_string(p->tm_year - 70) + "y " +
            std::to_string(p->tm_yday) + "d " + std::to_string(p->tm_hour) +
            "h " + std::to_string(p->tm_min) + "m " +
            std::to_string(p->tm_sec) + "s";

        return uptime;
    }

    /**
     * @brief Returns the system load average over the past 1 minute, 5 minutes
     *        and 15 minutes.
     *
     * @return std::string - The system load average
     */
    std::string getBMCLoadAvg() const
    {
        std::string loadavg{};

        std::ifstream loadavgFile{"/proc/loadavg"};
        std::string line;
        std::getline(loadavgFile, line);

        size_t count = 3;
        for (size_t i = 0; i < count; i++)
        {
            auto pos = line.find(" ");
            if (pos == std::string::npos)
            {
                return {};
            }

            if (i != count - 1)
            {
                loadavg.append(line.substr(0, pos + 1));
            }
            else
            {
                loadavg.append(line.substr(0, pos));
            }

            line = line.substr(pos + 1);
        }

        return loadavg;
    }

    /**
     * @brief Returns the 'send event logs to host' setting.
     *
     * @return bool - If sending PELs to the host is enabled.
     */
    virtual bool getHostPELEnablement() const
    {
        return _sendPELsToHost;
    }

    /**
     * @brief Returns the BMC state
     *
     * @return std::string - The BMC state property value
     */
    virtual std::string getBMCState() const
    {
        return _bmcState;
    }

    /**
     * @brief Returns the Chassis state
     *
     * @return std::string - The chassis state property value
     */
    virtual std::string getChassisState() const
    {
        return _chassisState;
    }

    /**
     * @brief Returns the chassis requested power
     *        transition value.
     *
     * @return std::string - The chassis transition property
     */
    virtual std::string getChassisTransition() const
    {
        return _chassisTransition;
    }

    /**
     * @brief Returns the Host state
     *
     * @return std::string - The Host state property value
     */
    virtual std::string getHostState() const
    {
        return _hostState;
    }

    /**
     * @brief Returns the Boot state
     *
     * @return std::string - The Boot state property value
     */
    virtual std::string getBootState() const
    {
        return _bootState;
    }

    /**
     * @brief Returns the motherboard CCIN
     *
     * @return std::string The motherboard CCIN
     */
    virtual std::string getMotherboardCCIN() const = 0;

    /**
     * @brief Returns the system IM
     *
     * @return std::string The system IM
     */
    virtual std::vector<uint8_t> getSystemIMKeyword() const = 0;

    /**
     * @brief Get the fields from the inventory necessary for doing
     *        a callout on an inventory path.
     *
     * @param[in] inventoryPath - The item to get the data for
     * @param[out] fruPartNumber - Filled in with the VINI/FN keyword
     * @param[out] ccin - Filled in with the VINI/CC keyword
     * @param[out] serialNumber - Filled in with the VINI/SN keyword
     */
    virtual void getHWCalloutFields(
        const std::string& inventoryPath, std::string& fruPartNumber,
        std::string& ccin, std::string& serialNumber) const = 0;

    /**
     * @brief Get the location code for an inventory item.
     *
     * @param[in] inventoryPath - The item to get the data for
     *
     * @return std::string - The location code
     */
    virtual std::string
        getLocationCode(const std::string& inventoryPath) const = 0;

    /**
     * @brief Get the list of system type names the system is called.
     *
     * @return std::vector<std::string> - The list of names
     */
    virtual std::vector<std::string> getSystemNames() const = 0;

    /**
     * @brief Fills in the placeholder 'Ufcs' in the passed in location
     *        code with the machine feature code and serial number, which
     *        is needed to create a valid location code.
     *
     * @param[in] locationCode - Location code value starting with Ufcs-, and
     *                           if that isn't present it will be added first.
     *
     * @param[in] node - The node number the location is on.
     *
     * @return std::string - The expanded location code
     */
    virtual std::string expandLocationCode(const std::string& locationCode,
                                           uint16_t node) const = 0;

    /**
     * @brief Returns the inventory paths for the FRU that the location
     *        code represents.
     *
     * @param[in] locationCode - If an expanded location code, then the
     *                           full location code.
     *                           If not expanded, a location code value
     *                           starting with Ufcs-, and if that isn't
     *                           present it will be added first.
     *
     * @param[in] node - The node number the location is on.  Ignored if the
     *                   expanded location code is passed in.
     *
     * @param[in] expanded - If the location code already has the relevent
     *                       VPD fields embedded in it.
     *
     * @return std::vector<std::string> - The inventory D-Bus objects
     */
    virtual std::vector<std::string>
        getInventoryFromLocCode(const std::string& LocationCode, uint16_t node,
                                bool expanded) const = 0;

    /**
     * @brief Sets the Asserted property on the LED group passed in.
     *
     * @param[in] ledGroup - The LED group D-Bus path
     * @param[in] value - The value to set it to
     */
    virtual void assertLEDGroup(const std::string& ledGroup,
                                bool value) const = 0;

    /**
     * @brief Sets the Functional property on the OperationalStatus
     *        interface on a D-Bus object.
     *
     * @param[in] objectPath - The D-Bus object path
     * @param[in] functional - The value
     */
    virtual void setFunctional(const std::string& objectPath,
                               bool functional) const = 0;

    /**
     * @brief Sets the critical association on the D-Bus object.
     *
     * @param[in] objectPath - The D-Bus object path
     */
    virtual void
        setCriticalAssociation(const std::string& objectPath) const = 0;

    /**
     * @brief Returns the manufacturing QuiesceOnError property
     *
     * @return bool - Manufacturing QuiesceOnError property
     */
    virtual bool getQuiesceOnError() const = 0;

    /**
     * @brief Split location code into base and connector segments
     *
     * A location code that ends in '-Tx', where 'x' is a number,
     * represents a connector, such as a USB cable connector.
     *
     * This function splits the passed in location code into a
     * base and connector segment.  e.g.:
     *   P0-T1 -> ['P0', '-T1']
     *   P0 -> ['P0', '']
     *
     * @param[in] locationCode - location code to split
     * @return pair<string, string> - The base and connector segments
     */
    static std::pair<std::string, std::string>
        extractConnectorFromLocCode(const std::string& locationCode);

    /**
     * @brief Returns the dump status
     *
     * @return bool dump status
     */
    virtual std::vector<bool>
        checkDumpStatus(const std::vector<std::string>& type) const = 0;

    /**
     * @brief Create guard record
     *
     *  @param[in] binPath: phal devtree binary path used as key
     *  @param[in] type: Guard type
     *  @param[in] logPath: error log entry object path
     */
    virtual void createGuardRecord(const std::vector<uint8_t>& binPath,
                                   const std::string& type,
                                   const std::string& logPath) const = 0;

    /**
     * @brief Create Progress SRC property on the boot progress
     *        interface on a D-Bus object.
     *
     * @param[in] priSRC - Primary SRC value (e.g. BD8D1001)
     * @param[in] srcStruct - Full SRC base structure
     */
    virtual void
        createProgressSRC(const uint64_t& priSRC,
                          const std::vector<uint8_t>& srcStruct) const = 0;

    /**
     * @brief Get the list of unresolved OpenBMC event log ids that have an
     * associated hardware isolation entry.
     *
     * @return std::vector<uint32_t> - The list of log ids
     */
    virtual std::vector<uint32_t> getLogIDWithHwIsolation() const = 0;

    /**
     * @brief Returns the latest raw progress SRC from the State.Boot.Raw
     *        D-Bus interface.
     *
     * @return std::vector<uint8_t> - The progress SRC bytes
     */
    virtual std::vector<uint8_t> getRawProgressSRC() const = 0;

    /**
     * @brief Returns the FRUs DI property value hosted on the VINI iterface for
     * the given location code.
     *
     * @param[in] locationCode - The location code of the FRU
     *
     * @return std::optional<std::vector<uint8_t>> -  The FRUs DI or
     * std::nullopt
     */
    virtual std::optional<std::vector<uint8_t>>
        getDIProperty(const std::string& locationCode) const = 0;

    /**
     * @brief Wrpper API to call pHAL API 'getFRUType()' and check whether the
     * given location code is DIMM or not
     *
     * @param[in] locCode - The location code of the FRU
     *
     * @return - true, if the given location code is DIMM
     *         - false, if the given location code is not DIMM or if it fails to
     *         determine the FRU type.
     */
    bool isDIMM(const std::string& locCode);

    /**
     * @brief Check whether the given location code present in the cache
     * memory
     *
     * @param[in] locCode - The location code of the FRU
     *
     * @return true, if the given location code present in cache and is a DIMM
     *         false, if the given location code present in cache, but a non
     *         DIMM FRU
     *         std::nullopt, if the given location code is not present in the
     *         cache.
     */
    std::optional<bool> isDIMMLocCode(const std::string& locCode) const;

    /**
     * @brief add the given location code to the cache memory
     *
     * @param[in] locCode - The location code of the FRU
     * @param[in] isFRUDIMM - true indicates the FRU is a DIMM
     *                        false indicates the FRU is a non DIMM
     *
     */
    void addDIMMLocCode(const std::string& locCode, bool isFRUDIMM);

  protected:
    /**
     * @brief Sets the host on/off state and runs any
     *        callback functions (if there was a change).
     */
    void setHostUp(bool hostUp)
    {
        if (_hostUp != hostUp)
        {
            _hostUp = hostUp;

            for (auto& [name, func] : _hostChangeCallbacks)
            {
                try
                {
                    func(_hostUp);
                }
                catch (const std::exception& e)
                {
                    lg2::error(
                        "A host state change callback threw an exception");
                }
            }
        }
    }

    /**
     * @brief Runs the callback functions registered when
     *        FRUs become present.
     */
    void setFruPresent(const std::string& locationCode)
    {
        for (const auto& [_, func] : _fruPresentCallbacks)
        {
            try
            {
                func(locationCode);
            }
            catch (const std::exception& e)
            {
                lg2::error("A FRU present callback threw an exception");
            }
        }
    }

    /**
     * @brief The hardware management console status.  Always kept
     *        up to date.
     */
    bool _hmcManaged = false;

    /**
     * @brief The host up status.  Always kept up to date.
     */
    bool _hostUp = false;

    /**
     * @brief The map of host state change subscriber
     *        names to callback functions.
     */
    std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;

    /**
     * @brief The map of FRU present subscriber
     *        names to callback functions.
     */
    std::map<std::string, FRUPresentFunc> _fruPresentCallbacks;

    /**
     * @brief The BMC firmware version string
     */
    std::string _bmcFWVersion;

    /**
     * @brief The server firmware version string
     */
    std::string _serverFWVersion;

    /**
     * @brief The BMC firmware version ID string
     */
    std::string _bmcFWVersionID;

    /**
     * @brief If sending PELs is enabled.
     *
     * This is usually set to false in manufacturing test.
     */
    bool _sendPELsToHost = true;

    /**
     * @brief The BMC state property
     */
    std::string _bmcState;

    /**
     * @brief The Chassis current power state property
     */
    std::string _chassisState;

    /**
     * @brief The Chassis requested power transition property
     */
    std::string _chassisTransition;

    /**
     * @brief The host state property
     */
    std::string _hostState;

    /**
     * @brief The boot state property
     */
    std::string _bootState;

    /**
     * @brief A cache storage for location code and its FRU Type
     *  - The key 'std::string' represents the locationCode of the FRU
     *  - The bool value - true indicates the FRU is a DIMM
     *                     false indicates the FRU is a non DIMM.
     */
    std::unordered_map<std::string, bool> _locationCache;
};

/**
 * @class DataInterface
 *
 * Concrete implementation of DataInterfaceBase.
 */
class DataInterface : public DataInterfaceBase
{
  public:
    DataInterface() = delete;
    ~DataInterface() = default;
    DataInterface(const DataInterface&) = default;
    DataInterface& operator=(const DataInterface&) = default;
    DataInterface(DataInterface&&) = default;
    DataInterface& operator=(DataInterface&&) = default;

    /**
     * @brief Constructor
     *
     * @param[in] bus - The sdbusplus bus object
     */
    explicit DataInterface(sdbusplus::bus_t& bus);

    /**
     * @brief Finds the D-Bus service name that hosts the
     *        passed in path and interface.
     *
     * @param[in] objectPath - The D-Bus object path
     * @param[in] interface - The D-Bus interface
     */
    DBusService getService(const std::string& objectPath,
                           const std::string& interface) const;

    /**
     * @brief Wrapper for the 'GetAll' properties method call
     *
     * @param[in] service - The D-Bus service to call it on
     * @param[in] objectPath - The D-Bus object path
     * @param[in] interface - The interface to get the props on
     *
     * @return DBusPropertyMap - The property results
     */
    DBusPropertyMap getAllProperties(const std::string& service,
                                     const std::string& objectPath,
                                     const std::string& interface) const;
    /**
     * @brief Wrapper for the 'Get' properties method call
     *
     * @param[in] service - The D-Bus service to call it on
     * @param[in] objectPath - The D-Bus object path
     * @param[in] interface - The interface to get the property on
     * @param[in] property - The property name
     * @param[out] value - Filled in with the property value.
     */
    void getProperty(const std::string& service, const std::string& objectPath,
                     const std::string& interface, const std::string& property,
                     DBusValue& value) const;
    /**
     * @brief Returns the machine Type/Model
     *
     * @return string - The machine Type/Model string
     */
    std::string getMachineTypeModel() const override;

    /**
     * @brief Returns the machine serial number
     *
     * @return string - The machine serial number
     */
    std::string getMachineSerialNumber() const override;

    /**
     * @brief Returns the motherboard CCIN
     *
     * @return std::string The motherboard CCIN
     */
    std::string getMotherboardCCIN() const override;

    /**
     * @brief Returns the system IM
     *
     * @return std::vector The system IM keyword in 4 byte vector
     */
    std::vector<uint8_t> getSystemIMKeyword() const override;

    /**
     * @brief Get the fields from the inventory necessary for doing
     *        a callout on an inventory path.
     *
     * @param[in] inventoryPath - The item to get the data for
     * @param[out] fruPartNumber - Filled in with the VINI/FN keyword
     * @param[out] ccin - Filled in with the VINI/CC keyword
     * @param[out] serialNumber - Filled in with the VINI/SN keyword
     */
    void getHWCalloutFields(const std::string& inventoryPath,
                            std::string& fruPartNumber, std::string& ccin,
                            std::string& serialNumber) const override;

    /**
     * @brief Get the location code for an inventory item.
     *
     * Throws an exception if the inventory item doesn't have the
     * location code interface.
     *
     * @param[in] inventoryPath - The item to get the data for
     *
     * @return std::string - The location code
     */
    std::string
        getLocationCode(const std::string& inventoryPath) const override;

    /**
     * @brief Get the list of system type names the system is called.
     *
     * @return std::vector<std::string> - The list of names
     */
    std::vector<std::string> getSystemNames() const override;

    /**
     * @brief Fills in the placeholder 'Ufcs' in the passed in location
     *        code with the machine feature code and serial number, which
     *        is needed to create a valid location code.
     *
     * @param[in] locationCode - Location code value starting with Ufcs-, and
     *                           if that isn't present it will be added first.
     *
     * @param[in] node - The node number the location is one.
     *
     * @return std::string - The expanded location code
     */
    std::string expandLocationCode(const std::string& locationCode,
                                   uint16_t node) const override;

    /**
     * @brief Returns the inventory paths for the FRU that the location
     *        code represents.
     *
     * @param[in] locationCode - If an expanded location code, then the
     *                           full location code.
     *                           If not expanded, a location code value
     *                           starting with Ufcs-, and if that isn't
     *                           present it will be added first.
     *
     * @param[in] node - The node number the location is on.  Ignored if the
     *                   expanded location code is passed in.
     *
     * @param[in] expanded - If the location code already has the relevent
     *                       VPD fields embedded in it.
     *
     * @return std::vector<std::string> - The inventory D-Bus objects
     */
    std::vector<std::string>
        getInventoryFromLocCode(const std::string& locationCode, uint16_t node,
                                bool expanded) const override;

    /**
     * @brief Sets the Asserted property on the LED group passed in.
     *
     * @param[in] ledGroup - The LED group D-Bus path
     * @param[in] value - The value to set it to
     */
    void assertLEDGroup(const std::string& ledGroup, bool value) const override;

    /**
     * @brief Sets the Functional property on the OperationalStatus
     *        interface on a D-Bus object.
     *
     * @param[in] objectPath - The D-Bus object path
     * @param[in] functional - The value
     */
    void setFunctional(const std::string& objectPath,
                       bool functional) const override;

    /**
     * @brief Sets the critical association on the D-Bus object.
     *
     * @param[in] objectPath - The D-Bus object path
     */
    void setCriticalAssociation(const std::string& objectPath) const override;

    /**
     * @brief Returns the manufacturing QuiesceOnError property
     *
     * @return bool - Manufacturing QuiesceOnError property
     */
    bool getQuiesceOnError() const override;

    /**
     * @brief Returns the dump status
     *
     * @param[in] type - The dump type to check for
     *
     * @return bool dump status
     */
    std::vector<bool>
        checkDumpStatus(const std::vector<std::string>& type) const override;

    /**
     * @brief Create guard record
     *
     *  @param[in] binPath: phal devtree binary path used as key
     *  @param[in] type: Guard type
     *  @param[in] logPath: error log entry object path
     */
    void createGuardRecord(const std::vector<uint8_t>& binPath,
                           const std::string& type,
                           const std::string& logPath) const override;

    /**
     * @brief Create Progress SRC property on the boot progress
     *        interface on a D-Bus object.
     *
     * @param[in] priSRC - Primary SRC value
     * @param[in] srcStruct - Full SRC base structure
     */
    void
        createProgressSRC(const uint64_t& priSRC,
                          const std::vector<uint8_t>& srcStruct) const override;

    /**
     * @brief Get the list of unresolved OpenBMC event log ids that have an
     * associated hardware isolation entry.
     *
     * @return std::vector<uint32_t> - The list of log ids
     */
    std::vector<uint32_t> getLogIDWithHwIsolation() const override;

    /**
     * @brief Returns the latest raw progress SRC from the State.Boot.Raw
     *        D-Bus interface.
     *
     * @return std::vector<uint8_t>: The progress SRC bytes
     */
    std::vector<uint8_t> getRawProgressSRC() const override;

    /**
     * @brief Returns the FRUs DI property value hosted on the VINI iterface for
     * the given location code.
     *
     * @param[in] locationCode - The location code of the FRU
     *
     * @return std::optional<std::vector<uint8_t>> -  The FRUs DI or
     * std::nullopt
     */
    std::optional<std::vector<uint8_t>>
        getDIProperty(const std::string& locationCode) const override;

  private:
    /**
     * @brief Reads the BMC firmware version string and puts it into
     *        _bmcFWVersion.
     */
    void readBMCFWVersion();

    /**
     * @brief Reads the server firmware version string and puts it into
     *        _serverFWVersion.
     */
    void readServerFWVersion();

    /**
     * @brief Reads the BMC firmware version ID and puts it into
     *        _bmcFWVersionID.
     */
    void readBMCFWVersionID();

    /**
     * @brief Finds all D-Bus paths that contain any of the interfaces
     *        passed in, by using GetSubTreePaths.
     *
     * @param[in] interfaces - The desired interfaces
     *
     * @return The D-Bus paths.
     */
    DBusPathList getPaths(const DBusInterfaceList& interfaces) const;

    /**
     * @brief The interfacesAdded callback used on the inventory to
     *        find the D-Bus object that has the motherboard interface.
     *        When the motherboard is found, it then adds a PropertyWatcher
     *        for the motherboard CCIN.
     */
    void motherboardIfaceAdded(sdbusplus::message_t& msg);

    /**
     * @brief Start watching for the hotpluggable FRUs to become
     *        present.
     */
    void startFruPlugWatch();

    /**
     * @brief Create a D-Bus match object for the Present property
     *        to change on the path passed in.
     * @param[in] path - The path to watch.
     */
    void addHotplugWatch(const std::string& path);

    /**
     * @brief Callback when an inventory interface was added.
     *
     * Only does something if it's one of the hotpluggable FRUs,
     * in which case it will treat it as a hotplug if the
     * Present property is true.
     *
     * @param[in] msg - The InterfacesAdded signal contents.
     */
    void inventoryIfaceAdded(sdbusplus::message_t& msg);

    /**
     * @brief Callback when the Present property changes.
     *
     * If present, will run the registered callbacks.
     *
     * @param[in] msg - The PropertiesChanged signal contents.
     */
    void presenceChanged(sdbusplus::message_t& msg);

    /**
     * @brief If the Present property is in the properties map
     *        passed in and it is true, notify the subscribers.
     *
     * @param[in] path - The object path of the inventory item.
     * @param[in] properties - The properties map
     */
    void notifyPresenceSubsribers(const std::string& path,
                                  const DBusPropertyMap& properties);

    /**
     * @brief Adds the Ufcs- prefix to the location code passed in
     *        if necessary.
     *
     * Needed because the location codes that come back from the
     * message registry and device callout JSON don't have it.
     *
     * @param[in] - The location code without a prefix, like P1-C1
     *
     * @return std::string - The location code with the prefix
     */
    static std::string addLocationCodePrefix(const std::string& locationCode);

    /**
     * @brief A helper API to check whether the PHAL device tree is exists,
     *        ensuring the PHAL init API can be invoked.
     *
     * @return true if the PHAL device tree is exists, otherwise false
     */
    bool isPHALDevTreeExist() const;

#ifdef PEL_ENABLE_PHAL
    /**
     * @brief A helper API to init PHAL libraries
     *
     * @return None
     */
    void initPHAL();
#endif // PEL_ENABLE_PHAL

    /**
     * @brief A helper API to subscribe to systemd signals
     *
     * @return None
     */
    void subscribeToSystemdSignals();

    /**
     * @brief A helper API to unsubscribe to systemd signals
     *
     * @return None
     */
    void unsubscribeFromSystemdSignals();

    /**
     * @brief The D-Bus property or interface watchers that have callbacks
     *        registered that will set members in this class when
     *        they change.
     */
    std::vector<std::unique_ptr<DBusWatcher>> _properties;

    std::unique_ptr<sdbusplus::bus::match_t> _invIaMatch;

    /**
     * @brief The matches for watching for hotplugs.
     *
     * A map so we can check that we never get duplicates.
     */
    std::map<std::string, std::unique_ptr<sdbusplus::bus::match_t>>
        _invPresentMatches;

    /**
     * @brief The sdbusplus bus object for making D-Bus calls.
     */
    sdbusplus::bus_t& _bus;

    /**
     * @brief Watcher to check "openpower-update-bios-attr-table" service
     *        is "done" to init PHAL libraires
     */
    std::unique_ptr<sdbusplus::bus::match_t> _systemdMatch;

    /**
     * @brief A slot object for async dbus call
     */
    sdbusplus::slot_t _systemdSlot;
};

} // namespace pels
} // namespace openpower
