/**
 * @file discover.h
 * @brief Public interface for Discover library
 */

/* $Progeny$
 *
 * Copyright 2001, 2002 Progeny Linux Systems, Inc.
 * Copyright 2002 Hewlett-Packard Company
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#ifndef DISCOVER_H
#define DISCOVER_H

#include <stdbool.h>

#ifdef __cplusplus
    extern "C" {
#endif

/**
 * @mainpage Discover API Reference
 *
 * This is the Discover application programming interface (API) reference.
 * If you have not already read <A
 * href="http://hackers.progeny.com/discover/doc/guide.html">The Discover
 * Hardware Detection System</A>, you should do so now.  The following list
 * describes the contents of the links at the top of the page:
 *
 *    - Main page -- This page
 *
 *    - Modules -- List of top-level modules; you probably want to
 *      start here, where navigation is fastest
 *
 *    - Data Structures -- List of data structures used by Discover
 *
 *    - File List -- List of files comprising Discover's external
 *      interface, with links to documentation and source code
 *
 *    - Data Fields -- List of fields used in Discover's structs and
 *      unions
 *
 *    - Globals -- List of global symbols, with links to file summaries
 *
 * The Discover library was written by Eric Gillespie, John R. Daily, and
 * Josh Bressers, with design input from Branden Robinson.
 *
 */

/**
 * @defgroup types Types
 * @{
 */

typedef enum {
    /** Success */
    DISCOVER_SUCCESS,
    /** Input/output error */
    DISCOVER_EIO,
    /** XML parse error */
    DISCOVER_EXML,
    /** System error */
    DISCOVER_ESYS,
    /** Disabled bus */
    DISCOVER_EBUSDISABLED,
    /** Bus not found */
    DISCOVER_EBUSNOTFOUND,
    /** Data source not found */
    DISCOVER_EDATANOTFOUND,
    /** Device not found */
    DISCOVER_EDEVICENOTFOUND,
    /** Invalid version range */
    DISCOVER_EBADVERSION,
    /** Action not implemented for this platform */
    DISCOVER_ENOIMPL
} discover_error_code_t;

struct discover_error;

/** Signature of functions that assist with creating message strings */
typedef void *(discover_create_message_t)(struct discover_error **, char *);

/**
 * All functions that perform some action (as opposed to returning a
 * member of a structure, for example) take an argument of this type.
 * It is used to report that the action succeeded, or why it failed.
 */
typedef struct discover_error {
    /** Return the error code value that is checked */
    discover_error_code_t code;
    /** String containing the message from the last error */
    char *message;
    /** Function pointer into a routine to create a message for us */
    discover_create_message_t *create_message;
} discover_error_t;

/** Mapping of bus names to functions */
typedef struct discover_bus_map         discover_bus_map_t;
/** Structure describing a device */
typedef struct discover_device          discover_device_t;
/** Data element from the device XML files */
typedef struct discover_data            discover_data_t;
/** Structure for mapping Discover device types to bus-specific classes */
typedef struct discover_xml_busclass    discover_xml_busclass_t;
/** Structure for mapping vendor names to bus-specific IDs */
typedef struct discover_xml_vendor      discover_xml_vendor_t;
/** Structure describing a URL where XML data can be found */
typedef struct discover_xml_url         discover_xml_url_t;

/** Signature of functions returning discover_device_t structures */
typedef discover_device_t *(discover_device_func_t)(discover_error_t *);
/** Signature of functions returning discover_xml_busclass_t structures */
typedef discover_xml_busclass_t *(discover_xml_busclass_func_t)(discover_error_t *);
/** Signature of functions returning discover_xml_vendor_t structures */
typedef discover_xml_vendor_t *(discover_xml_vendor_func_t)(discover_error_t *);
/** Signature of functions returning discover_xml_url_t structures */
typedef discover_xml_url_t *(discover_xml_url_func_t)(discover_error_t *);
/** Signature of functions that free internal lists */
typedef void (discover_free_func_t)(void);

#include <discover/sysdep.h>
/** Signature of functions that return sysdep_data_t lists */
typedef discover_sysdep_data_t *(discover_sysdep_raw_func_t)(void);

/**
 * Enumerate the buses.
 * */
typedef enum {
    ATA,
    PCI,
    PCMCIA,
    SCSI,
    USB
} discover_bus_t;

/**
 * Number of buses we support
 * */
#define BUS_COUNT 5

/**
 * Enumerate the types of data files: vendor, busclass, and device.
 * */
typedef enum {
    VENDOR_TYPE,
    BUSCLASS_TYPE,
    DEVICE_TYPE
} discover_filetype_t;


/**
 * Bus scanning information is loaded from the config file.  The
 * scan_default member may be set to 0 to avoid scanning a specified
 * bus.  If the scan_never flag is set, the bus will never be scanned; this
 * behavior is controlled from the config file.
 *
 * The function pointer exists to allow client code to override the
 * sysdeps; it is used by the unit tests provided with Discover.
 * */
struct discover_bus_map {
    /** Human-readable name */
    char *name;
    /** Boolean (sort of) defining the bus's default behavior */
    int scan_default;
    /** Never scan this bus if true */
    int scan_never;
    /** Function pointer that will acquire data */
    discover_sysdep_raw_func_t *get_raw;
};

/** @} */

/** Function responsible for returning a devicelist of current devices */
discover_device_t *discover_get_devices(discover_bus_t bus, discover_error_t *status);

/** Free the currently allocated memory holding the device information. */
void discover_free_devices(void);

discover_error_t *discover_error_new(void);
void discover_error_free(discover_error_t *status);
char *discover_strerror(discover_error_t *err);
int discover_major_version(void);
int discover_minor_version(void);
int discover_micro_version(void);

/******************************************************************************
 * discover_device
 */

discover_device_t *discover_device_new(void);

/* Class is "video", "sound", etc. */
discover_device_t *discover_device_find(char *discover_class,
                                             discover_error_t *status);

char *discover_device_get_data(discover_device_t *device,
                               char *path, char *version,
                               discover_error_t *status);

void
discover_device_copy(discover_device_t *src, discover_device_t *dst);

char *discover_device_get_busclass(discover_device_t *device);
char *discover_device_get_model_id(discover_device_t *device);
char *discover_device_get_model_name(discover_device_t *device);
char *discover_device_get_vendor_id(discover_device_t *device);
char *discover_device_get_vendor_name(discover_device_t *device);

discover_data_t *
discover_device_get_data_struct(discover_device_t *device);

discover_device_t *
discover_device_get_next(discover_device_t *device);

void discover_device_free(discover_device_t *devices, int free_data);

/******************************************************************************
 * discover_data
 */

discover_data_t *discover_data_new(void);

char *discover_data_get_class(discover_data_t *data);
char *discover_data_get_text(discover_data_t *data);
discover_data_t *discover_data_get_parent(discover_data_t *data);
discover_data_t *discover_data_get_child(discover_data_t *data);
discover_data_t *discover_data_get_next(discover_data_t *data);
discover_data_t *discover_data_get_prev(discover_data_t *prev);
discover_data_t *discover_data_get_first(discover_data_t *data);
void discover_data_free(discover_data_t *data_tree);

#ifdef __cplusplus
    }
#endif

#endif

/*
 * Local variables:
 * c-file-style: "progeny"
 * indent-tabs-mode: nil
 * End:
 */
/* vim: set cin fo=tcroq sw=4 et sts=4 tw=75: */
