#pragma once

#include "item_updater.hpp"

#include <string>

namespace openpower
{
namespace software
{
namespace updater
{

class GardResetUbi : public GardReset
{
  public:
    using GardReset::GardReset;
    virtual ~GardResetUbi() = default;

  protected:
    /**
     * @brief GUARD factory reset - clears the PNOR GUARD partition.
     */
    void reset() override;
};

/** @class ItemUpdaterUbi
 *  @brief Manages the activation of the host version items for ubi layout
 */
class ItemUpdaterUbi : public ItemUpdater
{
  public:
    ItemUpdaterUbi(sdbusplus::bus_t& bus, const std::string& path) :
        ItemUpdater(bus, path)
    {
        processPNORImage();
        gardReset = std::make_unique<GardResetUbi>(bus, GARD_PATH);
        volatileEnable = std::make_unique<ObjectEnable>(bus, volatilePath);

        // Emit deferred signal.
        emit_object_added();
    }
    virtual ~ItemUpdaterUbi() = default;

    void freePriority(uint8_t value, const std::string& versionId) override;

    void processPNORImage() override;

    bool erase(std::string entryId) override;

    void deleteAll() override;

    bool freeSpace() override;

    bool isVersionFunctional(const std::string& versionId) override;

    /** @brief Determine the software version id
     *         from the symlink target (e.g. /media/ro-2a1022fe).
     *
     * @param[in] symlinkPath - The path of the symlink.
     * @param[out] id - The version id as a string.
     */
    static std::string determineId(const std::string& symlinkPath);

  private:
    std::unique_ptr<Activation> createActivationObject(
        const std::string& path, const std::string& versionId,
        const std::string& extVersion,
        sdbusplus::xyz::openbmc_project::Software::server::Activation::
            Activations activationStatus,
        AssociationList& assocs) override;

    std::unique_ptr<Version> createVersionObject(
        const std::string& objPath, const std::string& versionId,
        const std::string& versionString,
        sdbusplus::xyz::openbmc_project::Software::server::Version::
            VersionPurpose versionPurpose,
        const std::string& filePath) override;

    bool validateImage(const std::string& path) override;

    /** @brief Host factory reset - clears PNOR partitions for each
     * Activation D-Bus object */
    void reset() override;

    /**
     * @brief Validates the presence of SquashFS image in the image dir.
     *
     * @param[in]  filePath - The path to the SquashFS image.
     * @param[out] result    - 0 --> if validation was successful
     *                       - -1--> Otherwise
     */
    static int validateSquashFSImage(const std::string& filePath);

    /** @brief Clears read only PNOR partition for
     *  given Activation D-Bus object
     *
     * @param[in]  versionId - The id of the ro partition to remove.
     */
    void removeReadOnlyPartition(const std::string& versionId);

    /** @brief Clears read write PNOR partition for
     *  given Activation D-Bus object
     *
     *  @param[in]  versionId - The id of the rw partition to remove.
     */
    void removeReadWritePartition(const std::string& versionId);

    /** @brief Clears preserved PNOR partition */
    void removePreservedPartition();
};

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