#pragma once

#include "config.h"

#include "xyz/openbmc_project/Common/FilePath/server.hpp"
#include "xyz/openbmc_project/Object/Delete/server.hpp"
#include "xyz/openbmc_project/Software/Version/server.hpp"

#include <sdbusplus/bus.hpp>

#include <string>

namespace openpower
{
namespace software
{
namespace updater
{

class ItemUpdater;

typedef std::function<void(std::string)> eraseFunc;

using VersionInherit = sdbusplus::server::object_t<
    sdbusplus::xyz::openbmc_project::Software::server::Version,
    sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
using DeleteInherit = sdbusplus::server::object_t<
    sdbusplus::xyz::openbmc_project::Object::server::Delete>;

namespace sdbusRule = sdbusplus::bus::match::rules;

class Delete;
class Version;

/** @class Delete
 *  @brief OpenBMC Delete implementation.
 *  @details A concrete implementation for xyz.openbmc_project.Object.Delete
 *  D-Bus API.
 */
class Delete : public DeleteInherit
{
  public:
    /** @brief Constructs Delete.
     *
     *  @param[in] bus    - The D-Bus bus object
     *  @param[in] path   - The D-Bus object path
     *  @param[in] parent - Parent object.
     */
    Delete(sdbusplus::bus_t& bus, const std::string& path, Version& parent) :
        DeleteInherit(bus, path.c_str(), action::emit_interface_added),
        parent(parent)
    {}

    /**
     * @brief Delete the D-Bus object.
     *        Overrides the default delete function by calling
     *        Version class erase Method.
     **/
    void delete_() override;

  private:
    /** @brief Parent Object. */
    Version& parent;
};

/** @class Version
 *  @brief OpenBMC version software management implementation.
 *  @details A concrete implementation for xyz.openbmc_project.Software.Version
 *  D-Bus API.
 */
class Version : public VersionInherit
{
  public:
    /** @brief Constructs Version Software Manager.
     *
     * @param[in] bus            - The D-Bus bus object
     * @param[in] objPath        - The D-Bus object path
     * @param[in] parent         - Parent object.
     * @param[in] versionId      - The version Id
     * @param[in] versionString  - The version string
     * @param[in] versionPurpose - The version purpose
     * @param[in] filePath       - The image filesystem path
     * @param[in] callback       - The eraseFunc callback
     */
    Version(sdbusplus::bus_t& bus, const std::string& objPath,
            ItemUpdater& parent, const std::string& versionId,
            const std::string& versionString, VersionPurpose versionPurpose,
            const std::string& filePath, eraseFunc callback) :
        VersionInherit(bus, (objPath).c_str(),
                       VersionInherit::action::defer_emit),
        eraseCallback(callback), bus(bus), objPath(objPath), parent(parent),
        versionId(versionId), versionStr(versionString),
        chassisStateSignals(
            bus,
            sdbusRule::type::signal() + sdbusRule::member("PropertiesChanged") +
                sdbusRule::path(CHASSIS_STATE_PATH) +
                sdbusRule::argN(0, CHASSIS_STATE_OBJ) +
                sdbusRule::interface(SYSTEMD_PROPERTY_INTERFACE),
            std::bind(std::mem_fn(&Version::updateDeleteInterface), this,
                      std::placeholders::_1))
    {
        // Set properties.
        purpose(versionPurpose);
        version(versionString);
        path(filePath);

        // Emit deferred signal.
        emit_object_added();
    }

    /**
     * @brief Update the Object.Delete interface for this activation
     *
     *        Update the delete interface based on whether or not this
     *        activation is currently functional. A functional activation
     *        will have no Object.Delete, while a non-functional activation
     *        will have one.
     *
     * @param[in]  msg       - Data associated with subscribed signal
     */
    void updateDeleteInterface(sdbusplus::message_t& msg);

    /**
     * @brief Read the manifest file to get the value of the key.
     *
     * @param[in] filePath - The path to the file which contains the value
     *                       of keys.
     * @param[in] keys     - A map of keys with empty values.
     *
     * @return The map of keys with filled values.
     **/
    static std::map<std::string, std::string>
        getValue(const std::string& filePath,
                 std::map<std::string, std::string> keys);

    /**
     * @brief Get version and extended version from VERSION partition string.
     *
     * @param[in] versionPart - The string containing the VERSION partition.
     *
     * @return The pair contains the version and extended version.
     **/
    static std::pair<std::string, std::string>
        getVersions(const std::string& versionPart);

    /**
     * @brief Calculate the version id from the version string.
     *
     * @details The version id is a unique 8 hexadecimal digit id
     *          calculated from the version string.
     *
     * @param[in] version - The image version string (e.g. v1.99.10-19).
     *
     * @return The id.
     */
    static std::string getId(const std::string& version);

    /** @brief Persistent Delete D-Bus object */
    std::unique_ptr<Delete> deleteObject;

    /** @brief The parent's erase callback. */
    eraseFunc eraseCallback;

  private:
    /** @brief Persistent sdbusplus DBus bus connection */
    sdbusplus::bus_t& bus;

    /** @brief Persistent DBus object path */
    std::string objPath;

    /** @brief Parent Object. */
    ItemUpdater& parent;

    /** @brief This Version's version Id */
    const std::string versionId;

    /** @brief This Version's version string */
    const std::string versionStr;

    /** @brief Used to subscribe to chassis power state changes **/
    sdbusplus::bus::match_t chassisStateSignals;
};

} // namespace updater
} // namespace software
} // namespace openpower
