#pragma once

#include <sdbusplus/bus.hpp>
#include "xyz/openbmc_project/Software/Version/server.hpp"
#include "xyz/openbmc_project/Common/FilePath/server.hpp"
#include "xyz/openbmc_project/Object/Delete/server.hpp"
#include "config.h"

namespace openpower
{
namespace software
{
namespace updater
{

class ItemUpdater;

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

using VersionInherit = sdbusplus::server::object::object<
    sdbusplus::xyz::openbmc_project::Software::server::Version,
    sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
using DeleteInherit = sdbusplus::server::object::object<
    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::bus& bus, const std::string& path, Version& parent) :
        DeleteInherit(bus, path.c_str(), true), parent(parent), bus(bus),
        path(path)
    {
        std::vector<std::string> interfaces({interface});
        bus.emit_interfaces_added(path.c_str(), interfaces);
    }

    ~Delete()
    {
        std::vector<std::string> interfaces({interface});
        bus.emit_interfaces_removed(path.c_str(), interfaces);
    }

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

    // TODO Remove once openbmc/openbmc#1975 is resolved
    static constexpr auto interface = "xyz.openbmc_project.Object.Delete";
    sdbusplus::bus::bus& bus;
    std::string path;
};

/** @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::bus& 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(), true),
        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))
    {
        // Bind erase method
        eraseCallback = callback;
        // 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::message& 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 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::bus& 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
