/*
 * libsysactivity
 * http://sourceforge.net/projects/libsysactivity/
 * Copyright (c) 2009, 2010 Carlos Olmedo Escobar <carlos.olmedo.e@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * \defgroup disk Disk statistics interface
 * @{
 */
#ifndef SA_DISK_H_
#define SA_DISK_H_

/** \struct sa_disk disk.h
 * This structure gathers the details about the activity of one disk.
 */
struct sa_disk {
#ifdef SA_DISK_NAME
	char name[SA_DISK_NAME]; //!< Device's name. It's used as the unique identifier of the device.
#endif
#ifdef SA_DISK_READS
	uint64_t reads; //!< Number of reads.
#endif
#ifdef SA_DISK_READS_MERGED
	uint64_t reads_merged; //!< Number of reads which are adjacent to each other and have been merged for efficiency
#endif
#ifdef SA_DISK_SECTORS_READ
	uint64_t sectors_read; //!< Total number of sectors read
#endif
#ifdef SA_DISK_TIME_SPENT_READING
	uint64_t time_spent_reading; //!< Number of seconds spent performing read operations
#endif
#ifdef SA_DISK_WRITES
	uint64_t writes; //!< Number of writes.
#endif
#ifdef SA_DISK_SECTORS_WRITTEN
	uint64_t sectors_written; //!< Total number of sectors written
#endif
#ifdef SA_DISK_TIME_SPENT_WRITING
	uint64_t time_spent_writing; //!< Number of seconds spent performing write operations
#endif
#ifdef SA_DISK_BYTES_READ
	uint64_t bytes_read; //!< Total number of bytes read
#endif
#ifdef SA_DISK_BYTES_WRITTEN
	uint64_t bytes_written; //!< Total number of bytes written
#endif
};

#ifdef SA_OPEN_DISK
/**
 * Prepares the resources needed for retrieving disk statistics. This function exists (and is needed) only when SA_OPEN_DISK is defined.
 * @return If successful 0 is returned, otherwise an error code is returned. If the operating system is not supported the return value will be ENOTSUP.
 * @see sa_close_disk()
 * @since 0.6.0
 */
int sa_open_disk(void) SA_EXPORT;
#endif

#ifdef SA_CLOSE_DISK
/**
 * This function closes the resources used for retrieving disk statistics. You should call it even when there was a previous error in another function of this API. This function exists (and is needed) only when SA_CLOSE_DISK is defined.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @see sa_open_disk()
 * @since 0.6.0
 */
int sa_close_disk(void) SA_EXPORT;
#endif

/**
 * Gives the total number of disks.
 * You don't need to call sa_reset_disks() before this function.
 * @param number The number will be stored here
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.6.0
 */
int sa_count_disks(uint16_t* number) SA_EXPORT SA_NONNULL;

/**
 * Refreshes the underlying operating system cache.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.6.0
 */
int sa_reset_disks() SA_EXPORT;

/**
 * Returns a list of the existing disks ids. The array will be fully populated even if it's not big enough (but ENOMEM is returned).
 * sa_reset_disks() should be called at least once before this function and everytime you need fresh values.
 * @param dst Where the statistics will be stored.
 * @param dst_size The number of ids that fits on the dst pointer.
 * @param written The number of disks ids written.
 * @return If successful 0 is returned, otherwise an error code is returned. ENODEV is returned when there are no more disks available.
 * @since 0.6.0
 */
int sa_get_disks_ids(char* dst, uint16_t dst_size, uint16_t* written) SA_EXPORT SA_NONNULL;

/**
 * Retrieves statistics from a disk identified by its device name.
 * sa_reset_disks() should be called at least once before this function and everytime you need fresh values.
 * @param name The name of the disk.
 * @param dst Where the statistics will be stored.
 * @return If successful 0 is returned, otherwise an error code is returned. ENODEV is returned when the requested device was not found.
 * @since 0.6.0
 */
int sa_get_disk(char* name, struct sa_disk* dst) SA_EXPORT SA_NONNULL;

/**
 * Retrieves statistics about all the disks' activity.
 * sa_reset_disks() should be called at least once before this function and everytime you need fresh values.
 * @param dst A buffer where the statistics will be stored.
 * @param dst_size The number of devices that fits in the dst buffer. If it's not big enough dst will be filled but ENOMEM will be returned.
 * @param written The amount of device statistics written.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.6.0
 */
int sa_get_disks(struct sa_disk* dst, uint16_t dst_size, uint16_t* written) SA_EXPORT SA_NONNULL;

/*@}*/
#endif /* SA_DISK_H_ */
