#pragma once

#include <libcryptsetup.h>

#include <phosphor-logging/lg2.hpp>
#include <stdplus/handle/managed.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

#include <string>
#include <string_view>

namespace estoraged
{

using sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound;

/** @class CryptsetupInterface
 *  @brief Interface to the cryptsetup functions used to manage a LUKS device.
 *  @details This class is used to mock out the cryptsetup functions.
 */
class CryptsetupInterface
{
  public:
    virtual ~CryptsetupInterface() = default;
    CryptsetupInterface() = default;
    CryptsetupInterface(const CryptsetupInterface&) = delete;
    CryptsetupInterface& operator=(const CryptsetupInterface&) = delete;

    CryptsetupInterface(CryptsetupInterface&&) = delete;
    CryptsetupInterface& operator=(CryptsetupInterface&&) = delete;

    /** @brief Wrapper around crypt_format.
     *  @details Used for mocking purposes.
     *
     *  @param[in] cd - crypt device handle.
     *  @param[in] type - type of device (optional params struct must be of
     *    this type).
     *  @param[in] cipher - (e.g. "aes").
     *  @params[in cipher_mode - including IV specification (e.g. "xts-plain").
     *  @params[in] uuid - requested UUID or NULL if it should be generated.
     *  @params[in] volume_key - pre-generated volume key or NULL if it should
     *    be generated (only for LUKS).
     *  @params[in] volume_key_size - size of volume key in bytes.
     *  @params[in] params - crypt type specific parameters.
     *
     *  @returns 0 on success or negative errno value otherwise.
     */
    virtual int cryptFormat(struct crypt_device* cd, const char* type,
                            const char* cipher, const char* cipherMode,
                            const char* uuid, const char* volumeKey,
                            size_t volumeKeySize, void* params) = 0;

    /** @brief Wrapper around crypt_keyslot_change_by_passphrase.
     *  @details Used for mocking purposes.
     *
     *  @param[in] cd - crypt device handle.
     *  @param[in] keyslotOld - old keyslot or CRYPT_ANY_SLOT.
     *  @param[in] keyslotNew - new keyslot or CRYPT_ANY_SLOT.
     *  @param[in] passphrase - passphrase for new keyslot.
     *  @param[in] passphraseSize - size of passphrase.
     *  @param[in] newPassphrase - new passphrase for the specified keyslot
     *  @param[in] newPassphraseSize - size of newPassphrase (in bytes).
     *
     *  @returns allocated key slot number or negative errno otherwise.
     */
    virtual int cryptKeyslotChangeByPassphrase(
        struct crypt_device* cd, int keyslotOld, int keyslotNew,
        const char* passphrase, size_t passphraseSize,
        const char* newPassphrase, size_t newPassphraseSize) = 0;

    /** @brief Wrapper around crypt_keyslot_add_by_volume_key.
     *  @details Used for mocking purposes.
     *
     *  @param[in] cd - crypt device handle.
     *  @param[in] keyslot - requested keyslot or CRYPT_ANY_SLOT.
     *  @param[in] volume_key - provided volume key or NULL if used after
     *    crypt_format.
     *  @param[in] volume_key_size - size of volume_key.
     *  @param[in] passphrase - passphrase for new keyslot.
     *  @param[in] passphrase_size - size of passphrase.
     *
     *  @returns allocated key slot number or negative errno otherwise.
     */
    virtual int cryptKeyslotAddByVolumeKey(
        struct crypt_device* cd, int keyslot, const char* volumeKey,
        size_t volumeKeySize, const char* passphrase,
        size_t passphraseSize) = 0;

    /** @brief Wrapper around crypt_load.
     *  @details Used for mocking purposes.
     *
     *  @param[in] cd - crypt device handle.
     *  @param[in] requested_type - crypt-type or NULL for all known.
     *  @param[in] params - crypt type specific parameters (see crypt-type).
     *
     *  @returns 0 on success or negative errno value otherwise.
     */
    virtual int cryptLoad(struct crypt_device* cd, const char* requestedType,
                          void* params) = 0;

    /** @brief Wrapper around crypt_activate_by_passphrase.
     *  @details Used for mocking purposes.
     *
     *  @param[in] cd - crypt device handle.
     *  @param[in] name - name of device to create, if NULL only check
     *    passphrase.
     *  @param[in] keyslot - requested keyslot to check or CRYPT_ANY_SLOT.
     *  @param[in] passphrase - passphrase used to unlock volume key.
     *  @param[in] passphrase_size - size of passphrase.
     *  @param[in] flags - activation flags.
     *
     *  @returns unlocked key slot number or negative errno otherwise.
     */
    virtual int cryptActivateByPassphrase(
        struct crypt_device* cd, const char* name, int keyslot,
        const char* passphrase, size_t passphraseSize, uint32_t flags) = 0;

    /** @brief Wrapper around crypt_deactivate.
     *  @details Used for mocking purposes.
     *
     *  @param[in] cd - crypt device handle, can be NULL.
     *  @param[in] name - name of device to deactivate.
     *
     *  @returns 0 on success or negative errno value otherwise.
     */
    virtual int cryptDeactivate(struct crypt_device* cd, const char* name) = 0;

    /** @brief Wrapper around crypt_keyslot_destory.
     *  @details Used for mocking purposes.
     *
     *  @param[in] cd - crypt device handle, can not be NULL.
     *  @param[in] keyslot requested key slot to destroy
     *
     *  @returns 0 on success or negative errno value otherwise.
     */
    virtual int cryptKeyslotDestroy(struct crypt_device* cd, int keyslot) = 0;

    /** @brief Wrapper around crypt_keyslot_max
     *  @details Used for mocking purposes.
     *
     * @param type crypt device type
     *
     * @return slot count or negative errno otherwise if device
     * does not support keyslots.
     */
    virtual int cryptKeySlotMax(const char* type) = 0;

    /** @brief Wrapper around crypt_keyslot_status
     *  @details Used for mocking purposes.
     *  Get information about particular key slot.
     *
     * @param cd crypt device handle
     * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT
     *
     * @return value defined by crypt_keyslot_info
     */
    virtual crypt_keyslot_info
        cryptKeySlotStatus(struct crypt_device* cd, int keyslot) = 0;

    /** @brief Wrapper around crypt_get_dir.
     *  @details Used for mocking purposes.
     *
     *  @returns the directory where mapped crypt devices are created.
     */
    virtual std::string cryptGetDir() = 0;
};

/** @class Cryptsetup
 *  @brief Implements CryptsetupInterface.
 */
class Cryptsetup : public CryptsetupInterface
{
  public:
    ~Cryptsetup() override = default;

    Cryptsetup() = default;
    Cryptsetup(const Cryptsetup&) = delete;
    Cryptsetup& operator=(const Cryptsetup&) = delete;

    Cryptsetup(Cryptsetup&&) = delete;
    Cryptsetup& operator=(Cryptsetup&&) = delete;
    int cryptFormat(struct crypt_device* cd, const char* type,
                    const char* cipher, const char* cipherMode,
                    const char* uuid, const char* volumeKey,
                    size_t volumeKeySize, void* params) override
    {
        return crypt_format(cd, type, cipher, cipherMode, uuid, volumeKey,
                            volumeKeySize, params);
    }

    int cryptKeyslotChangeByPassphrase(
        struct crypt_device* cd, int keyslotOld, int keyslotNew,
        const char* passphrase, size_t passphraseSize,
        const char* newPassphrase, size_t newPassphraseSize) override
    {
        return crypt_keyslot_change_by_passphrase(
            cd, keyslotOld, keyslotNew, passphrase, passphraseSize,
            newPassphrase, newPassphraseSize);
    }

    int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
                                   const char* volumeKey, size_t volumeKeySize,
                                   const char* passphrase,
                                   size_t passphraseSize) override
    {
        return crypt_keyslot_add_by_volume_key(
            cd, keyslot, volumeKey, volumeKeySize, passphrase, passphraseSize);
    }

    int cryptLoad(struct crypt_device* cd, const char* requestedType,
                  void* params) override
    {
        return crypt_load(cd, requestedType, params);
    }

    int cryptActivateByPassphrase(
        struct crypt_device* cd, const char* name, int keyslot,
        const char* passphrase, size_t passphraseSize, uint32_t flags) override
    {
        return crypt_activate_by_passphrase(cd, name, keyslot, passphrase,
                                            passphraseSize, flags);
    }

    int cryptDeactivate(struct crypt_device* cd, const char* name) override
    {
        return crypt_deactivate(cd, name);
    }

    int cryptKeyslotDestroy(struct crypt_device* cd, const int keyslot) override
    {
        return crypt_keyslot_destroy(cd, keyslot);
    }

    int cryptKeySlotMax(const char* type) override
    {
        return crypt_keyslot_max(type);
    }

    crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd,
                                          int keyslot) override
    {
        return crypt_keyslot_status(cd, keyslot);
    }

    std::string cryptGetDir() override
    {
        return {crypt_get_dir()};
    }
};

/** @class CryptHandle
 *  @brief This manages a crypt_device struct and automatically frees it when
 *  this handle exits the current scope.
 */
class CryptHandle
{
  public:
    /** @brief Constructor for CryptHandle
     *
     *  @param[in] device - path to device file
     */
    explicit CryptHandle(const std::string_view& device) : handle(init(device))
    {}

    /** @brief Get a pointer to the crypt_device struct. */
    struct crypt_device* get()
    {
        if (*handle == nullptr)
        {
            lg2::error("Failed to get crypt device handle",
                       "REDFISH_MESSAGE_ID",
                       std::string("OpenBMC.0.1.HandleGetFail"));
            throw ResourceNotFound();
        }

        return *handle;
    }

  private:
    /** @brief Allocate and initialize the crypt_device struct
     *
     *  @param[in] device - path to device file
     */
    struct crypt_device* init(const std::string_view& device)
    {
        struct crypt_device* cryptDev = nullptr;
        int retval = crypt_init(&cryptDev, device.data());
        if (retval < 0)
        {
            lg2::error("Failed to crypt_init", "REDFISH_MESSAGE_ID",
                       std::string("OpenBMC.0.1.InitFail"));
            throw ResourceNotFound();
        }

        return cryptDev;
    }

    /** @brief Free the crypt_device struct
     *
     *  @param[in] cd - pointer to crypt_device*, to be freed
     */
    static void cryptFree(struct crypt_device*&& cd)
    {
        crypt_free(cd);
    }

    /** @brief Managed handle to crypt_device struct */
    stdplus::Managed<struct crypt_device*>::Handle<cryptFree> handle;
};

} // namespace estoraged
