#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 <filesystem>
#include <fstream>

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;

  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;
};

/**
 * @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;

  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 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;
};

} // namespace pels
} // namespace openpower
