#include <glib.h>
#include <blockdev/utils.h>


#ifndef BD_DM_API
#define BD_DM_API

GQuark  bd_dm_error_quark (void);


#define BD_DM_ERROR bd_dm_error_quark ()
typedef enum {
    BD_DM_ERROR_TECH_UNAVAIL,
    BD_DM_ERROR_SYS,
    BD_DM_ERROR_NOT_ROOT,
    BD_DM_ERROR_TASK,
    BD_DM_ERROR_RAID_FAIL,
    BD_DM_ERROR_RAID_NO_DEVS,
    BD_DM_ERROR_RAID_NO_EXIST,
    BD_DM_ERROR_DEVICE_NOEXIST,
} BDDMError;

typedef enum {
    BD_DM_TECH_MAP = 0,
} BDDMTech;

typedef enum {
    BD_DM_TECH_MODE_CREATE_ACTIVATE   = 1 << 0,
    BD_DM_TECH_MODE_REMOVE_DEACTIVATE = 1 << 1,
    BD_DM_TECH_MODE_QUERY             = 1 << 2,
} BDDMTechMode;

/**
 * bd_dm_is_tech_avail:
 * @tech: the queried tech
 * @mode: a bit mask of queried modes of operation (#BDDMTechMode) for @tech
 * @error: (out) (optional): place to store error (details about why the @tech-@mode combination is not available)
 *
 * Returns: whether the @tech-@mode combination is available -- supported by the
 *          plugin implementation and having all the runtime dependencies available
 */
gboolean  bd_dm_is_tech_avail (BDDMTech tech, guint64 mode, GError **error);


/**
 * bd_dm_create_linear:
 * @map_name: name of the map
 * @device: device to create map for
 * @length: length of the mapping in sectors
 * @uuid: (nullable): UUID for the new dev mapper device or %NULL if not specified
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the new linear mapping @map_name was successfully created
 * for the @device or not
 *
 * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_CREATE_ACTIVATE
 */
gboolean  bd_dm_create_linear (const gchar *map_name, const gchar *device, guint64 length, const gchar *uuid, GError **error);


/**
 * bd_dm_remove:
 * @map_name: name of the map to remove
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the @map_name map was successfully removed or not
 *
 * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_REMOVE_DEACTIVATE
 */
gboolean  bd_dm_remove (const gchar *map_name, GError **error);


/**
 * bd_dm_name_from_node:
 * @dm_node: name of the DM node (e.g. "dm-0")
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: map name of the map providing the @dm_node device or %NULL
 * (@error) contains the error in such cases
 *
 * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY
 */
gchar* bd_dm_name_from_node (const gchar *dm_node, GError **error);


/**
 * bd_dm_node_from_name:
 * @map_name: name of the queried DM map
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: DM node name for the @map_name map or %NULL (@error) contains
 * the error in such cases
 *
 * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY
 */
gchar* bd_dm_node_from_name (const gchar *map_name, GError **error);


/**
 * bd_dm_get_subsystem_from_name:
 * @device_name: name of the device
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: subsystem of the given device
 *
 * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY
 */
gchar* bd_dm_get_subsystem_from_name (const gchar *device_name, GError **error);


/**
 * bd_dm_map_exists:
 * @map_name: name of the queried map
 * @live_only: whether to go through the live maps only or not
 * @active_only: whether to ignore suspended maps or not
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the given @map_name exists (and is live if @live_only is
 * %TRUE (and is active if @active_only is %TRUE)). If %FALSE is returned,
 * @error indicates whether error appeared (non-%NULL) or not (%NULL).
 *
 * Tech category: %BD_DM_TECH_MAP-%BD_DM_TECH_MODE_QUERY
 */
gboolean  bd_dm_map_exists (const gchar *map_name, gboolean live_only, gboolean active_only, GError **error);


#endif  /* BD_DM_API */
