/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2005, 2007 Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

/** \file unit.c */

/**
 * \addtogroup PedUnit
 * 
 * \brief The PedUnit module provides a standard mechanism for describing
 * and parsing locations within devices in human-friendly plain text. 
 *
 * Internally, libparted uses PedSector (which is typedef'ed to be long long 
 * in <parted/device.h>) to describe device locations such as the start and 
 * end of partitions.  However, sector numbers are often long and unintuitive.  
 * For example, my extended partition starts at sector 208845.  PedUnit allows 
 * this location to be represented in more intutitive ways, including "106Mb", 
 * "0Gb" and "0%", as well as "208845s".  PedUnit aims to provide facilities 
 * to provide a consistent system for describing device locations all
 * throughout libparted.
 * 
 * PedUnit provides two basic services: converting a PedSector into a text
 * representation, and parsing a text representation into a PedSector.
 * PedUnit currently supports these units:
 * 
 * 	sectors, bytes, kilobytes, megabytes, gigabytes, terabytes, compact,
 * 	cylinder and percent.
 * 	
 * PedUnit has a global variable that contains the default unit for all
 * conversions.
 *
 * @{
 */




#include <config.h>
#include <parted/parted.h>
#include <parted/debug.h>

#include <ctype.h>
#include <stdio.h>
#include <float.h>

#define N_(String) String
#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) dgettext (PACKAGE, String)
#else
#  define _(String) (String)
#endif /* ENABLE_NLS */


static PedUnit default_unit = PED_UNIT_COMPACT;
static const char* unit_names[] = {
	"s",
	"B",
	"kB",
	"MB",
	"GB",
	"TB",
	"compact",
	"cyl",
	"chs",
	"%",
	"kiB",
	"MiB",
	"GiB",
	"TiB"
};


/**
 * \brief Set the default \p unit used by subsequent calls to the PedUnit API.
 *
 * In particular, this affects how locations inside error messages
 * (exceptions) are displayed.
 */
void
ped_unit_set_default (PedUnit unit)
{
	default_unit = unit;
}


/**
 * \brief Get the current default unit.
 */
PedUnit
ped_unit_get_default ()
{
	return default_unit;
}

/**
 * Get the byte size of a given \p unit.
 */
long long
ped_unit_get_size (const PedDevice* dev, PedUnit unit)
{
	PedSector cyl_size = dev->bios_geom.heads * dev->bios_geom.sectors;

	switch (unit) {
		case PED_UNIT_SECTOR:	return dev->sector_size;
		case PED_UNIT_BYTE:	return 1;
		case PED_UNIT_KILOBYTE:	return PED_KILOBYTE_SIZE;
		case PED_UNIT_MEGABYTE:	return PED_MEGABYTE_SIZE;
		case PED_UNIT_GIGABYTE:	return PED_GIGABYTE_SIZE;
		case PED_UNIT_TERABYTE:	return PED_TERABYTE_SIZE;
		case PED_UNIT_KIBIBYTE:	return PED_KIBIBYTE_SIZE;
		case PED_UNIT_MEBIBYTE:	return PED_MEBIBYTE_SIZE;
		case PED_UNIT_GIBIBYTE:	return PED_GIBIBYTE_SIZE;
		case PED_UNIT_TEBIBYTE:	return PED_TEBIBYTE_SIZE;
		case PED_UNIT_CYLINDER:	return cyl_size * dev->sector_size;
		case PED_UNIT_CHS:	return dev->sector_size;

		case PED_UNIT_PERCENT:
			return dev->length * dev->sector_size / 100;

		case PED_UNIT_COMPACT:
			ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("Cannot get unit size for special unit "
				  "'COMPACT'."));
			return 0;
	}

	/* never reached */
	PED_ASSERT(0, return 0);
	return 0;
}

/**
 * Get a textual (non-internationalized) representation of a \p unit.
 * 
 * For example, the textual representation of PED_UNIT_SECTOR is "s".
 */
const char*
ped_unit_get_name (PedUnit unit)
{
	return unit_names[unit];
}

/**
 * Get a unit based on its textual representation: \p unit_name.
 *
 * For example, ped_unit_get_by_name("Mb") returns PED_UNIT_MEGABYTE.
 */
PedUnit
ped_unit_get_by_name (const char* unit_name)
{
	PedUnit unit;
	for (unit = PED_UNIT_FIRST; unit <= PED_UNIT_LAST; unit++) {
		if (!strcasecmp (unit_names[unit], unit_name))
			return unit;
	}
	return -1;
}

static char*
ped_strdup (const char *str)
{
	char *result;
	result = ped_malloc (strlen (str) + 1);
	if (!result)
		return NULL;
	strcpy (result, str);
	return result;
}

/**
 * \brief Get a string that describes the location of the \p byte on
 * device \p dev.
 * 
 * The string is described with the desired \p unit.
 * The returned string must be freed with ped_free().
 */
char*
ped_unit_format_custom_byte (const PedDevice* dev, PedSector byte, PedUnit unit)
{
	char buf[100];
	PedSector sector = byte / dev->sector_size;
	double d, w;
	int p;

	PED_ASSERT (dev != NULL, return NULL);
	
	/* CHS has a special comma-separated format. */
	if (unit == PED_UNIT_CHS) {
		const PedCHSGeometry *chs = &dev->bios_geom;
		snprintf (buf, 100, "%lld,%lld,%lld",
			  sector / chs->sectors / chs->heads,
			  (sector / chs->sectors) % chs->heads,
			  sector % chs->sectors);
		return ped_strdup (buf);
	}

	/* Cylinders, sectors and bytes should be rounded down... */
	if (unit == PED_UNIT_CYLINDER
	    || unit == PED_UNIT_SECTOR
	    || unit == PED_UNIT_BYTE) {
		snprintf (buf, 100, "%lld%s",
			  byte / ped_unit_get_size (dev, unit),
			  ped_unit_get_name (unit));
		return ped_strdup (buf);
	}
	
        if (unit == PED_UNIT_COMPACT) {
                if (byte >= 10LL * PED_TERABYTE_SIZE)
                        unit = PED_UNIT_TERABYTE;
                else if (byte >= 10LL * PED_GIGABYTE_SIZE)
                        unit = PED_UNIT_GIGABYTE;
                else if (byte >= 10LL * PED_MEGABYTE_SIZE)
                        unit = PED_UNIT_MEGABYTE;
                else if (byte >= 10LL * PED_KILOBYTE_SIZE)
                        unit = PED_UNIT_KILOBYTE;
                else
                        unit = PED_UNIT_BYTE;
	}

	/* IEEE754 says that 100.5 has to be rounded to 100 (by printf) */
	/* but 101.5 has to be rounded to 102... so we multiply by 1+E. */
	/* This just divide by 2 the natural IEEE754 extended precision */
	/* and won't cause any trouble before 1000 TB */
	d = ((double)byte / (double)ped_unit_get_size (dev, unit))
	    * (1. + DBL_EPSILON);
	w = d + ( (d < 10. ) ? 0.005 :
		  (d < 100.) ? 0.05  :
			       0.5  );
	p = (w < 10. ) ? 2 :
	    (w < 100.) ? 1 :
			 0 ;

#ifdef __BEOS__
	snprintf (buf, 100, "%.*f%s", p, d, ped_unit_get_name(unit));
#else
	snprintf (buf, 100, "%1$.*2$f%3$s", d, p, ped_unit_get_name (unit));
#endif

	return ped_strdup (buf);
}

/**
 * \brief Get a string that describes the location of the \p byte on
 * device \p dev.
 * 
 * The string is described with the default unit, which is set
 * by ped_unit_set_default().
 * The returned string must be freed with ped_free().
 */
char*
ped_unit_format_byte (const PedDevice* dev, PedSector byte)
{
	PED_ASSERT (dev != NULL, return NULL);
	return ped_unit_format_custom_byte (dev, byte, default_unit);
}

/**
 * \brief Get a string that describes the location \p sector on device \p dev.
 * 
 * The string is described with the desired \p unit.
 * The returned string must be freed with ped_free().
 */
char*
ped_unit_format_custom (const PedDevice* dev, PedSector sector, PedUnit unit)
{
	PED_ASSERT (dev != NULL, return NULL);
	return ped_unit_format_custom_byte(dev, sector*dev->sector_size, unit);
}

/**
 * \brief Get a string that describes the location \p sector on device \p dev.
 * 
 * The string is described with the default unit, which is set
 * by ped_unit_set_default().
 * The returned string must be freed with ped_free().
 */
char*
ped_unit_format (const PedDevice* dev, PedSector sector)
{
	PED_ASSERT (dev != NULL, return NULL);
	return ped_unit_format_custom_byte (dev, sector * dev->sector_size,
					    default_unit);
}

/**
 * If \p str contains a valid description of a location on \p dev, 
 * then \p *sector is modified to describe the location and a geometry 
 * is created in \p *range describing a 2 units large area centered on 
 * \p *sector.  If the \p range as described here would be partially outside 
 * the device \p dev, the geometry returned is the intersection between the 
 * former and the whole	device geometry.  If no units are specified, then the 
 * default unit is assumed.  
 *
 * \return \c 1 if \p str is a valid location description, \c 0 otherwise
 */
int
ped_unit_parse (const char* str, const PedDevice* dev, PedSector *sector,
		PedGeometry** range)
{
	return ped_unit_parse_custom (str, dev, default_unit, sector, range);
}

/* Inefficiently removes all spaces from a string, in-place. */
static void
strip_string (char* str)
{
	int i;

	for (i = 0; str[i] != 0; i++) {
		if (isspace (str[i])) {
			int j;
			for (j = i + 1; str[j] != 0; j++)
				str[j - 1] = str[j];
		}
	}
}


/* Find non-number suffix.  Eg: find_suffix("32Mb") returns a pointer to
 * "Mb". */
static char*
find_suffix (const char* str)
{
	while (str[0] != 0 && (isdigit (str[0]) || strchr(",.-", str[0])))
		str++;
	return (char *) str;
}

static void
remove_punct (char* str)
{
	int i = 0;

	for (i = 0; str[i]; i++) {
		if (ispunct (str[i]))
			str[i] = ' ';
	}
}

static int
is_chs (const char* str)
{
	int punct_count = 0;
	int i = 0;

	for (i = 0; str[i]; i++)
		punct_count += ispunct (str[i]) != 0;
	return punct_count == 2;
}

static int
parse_chs (const char* str, const PedDevice* dev, PedSector* sector,
		PedGeometry** range)
{
	PedSector cyl_size = dev->bios_geom.heads * dev->bios_geom.sectors;
	char* copy = ped_strdup (str);
	PedCHSGeometry chs;

	copy = ped_strdup (str);
	if (!copy)
		return 0;
	strip_string (copy);
	remove_punct (copy);

	if (sscanf (copy, "%d %d %d",
		    &chs.cylinders, &chs.heads, &chs.sectors) != 3) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("\"%s\" has invalid syntax for locations."),
				copy);
		goto error_free_copy;
	}

	if (chs.heads >= dev->bios_geom.heads) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The maximum head value is %d."),
				dev->bios_geom.heads - 1);
		goto error_free_copy;
	}
	if (chs.sectors >= dev->bios_geom.sectors) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The maximum sector value is %d."),
				dev->bios_geom.sectors - 1);
		goto error_free_copy;
	}

	*sector = 1LL * chs.cylinders * cyl_size
		+ chs.heads * dev->bios_geom.sectors
		+ chs.sectors;

	if (*sector >= dev->length) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The location %s is outside of the "
				  "device %s."),
				str, dev->path);
		goto error_free_copy;
	}
	if (range)
		*range = ped_geometry_new (dev, *sector, 1);
	ped_free (copy);
	return !range || *range != NULL;

error_free_copy:
	ped_free (copy);
	*sector = 0;
	if (range)
		*range = NULL;
	return 0;
}

static PedSector
clip (const PedDevice* dev, PedSector sector)
{
	if (sector < 0)
		return 0;
	if (sector > dev->length - 1)
		return dev->length - 1;
	return sector;
}

static PedGeometry*
geometry_from_centre_radius (const PedDevice* dev,
                             PedSector sector, PedSector radius)
{
	PedSector start = clip (dev, sector - radius);
	PedSector end = clip (dev, sector + radius);
	if (sector - end > radius || start - sector > radius)
		return NULL;
	return ped_geometry_new (dev, start, end - start + 1);
}

static PedUnit
parse_unit_suffix (const char* suffix, PedUnit suggested_unit)
{
	if (strlen (suffix) > 1 && tolower (suffix[1]) == 'i') {
		switch (tolower (suffix[0])) {
			case 'k': return PED_UNIT_KIBIBYTE;
			case 'm': return PED_UNIT_MEBIBYTE;
			case 'g': return PED_UNIT_GIBIBYTE;
			case 't': return PED_UNIT_TEBIBYTE;
		}
	} else if (strlen (suffix) > 0) {
		switch (tolower (suffix[0])) {
			case 's': return PED_UNIT_SECTOR;
			case 'b': return PED_UNIT_BYTE;
			case 'k': return PED_UNIT_KILOBYTE;
			case 'm': return PED_UNIT_MEGABYTE;
			case 'g': return PED_UNIT_GIGABYTE; 
			case 't': return PED_UNIT_TERABYTE;
			case 'c': return PED_UNIT_CYLINDER; 
			case '%': return PED_UNIT_PERCENT;
		}
	}

	if (suggested_unit == PED_UNIT_COMPACT) {
		if (default_unit == PED_UNIT_COMPACT)
			return PED_UNIT_MEGABYTE;
		else
			return default_unit;
	}

	return suggested_unit;
}

/**
 * If \p str contains a valid description of a location on \p dev, then 
 * \p *sector is modified to describe the location and a geometry is created
 * in \p *range describing a 2 units large area centered on \p *sector.  If the
 * \p range as described here would be partially outside the device \p dev, the
 * geometry returned is the intersection between the former and the whole
 * device geometry.  If no units are specified, then the default unit is
 * assumed. 
 *
 * \throws PED_EXCEPTION_ERROR if \p str contains invalid description of a
 * location
 * \throws PED_EXCEPTION_ERROR if location described by \p str 
 * is outside of the device \p dev->path
 *
 * \return \c 1 if \p str is a valid location description, \c 0 otherwise.
 */
int
ped_unit_parse_custom (const char* str, const PedDevice* dev, PedUnit unit,
		       PedSector* sector, PedGeometry** range)
{
	char*     copy;
	char*     suffix;
	double    num;
	long long unit_size;
	PedSector radius;

	if (is_chs (str))
		return parse_chs (str, dev, sector, range);

	copy = ped_strdup (str);
	if (!copy)
		goto error;
	strip_string (copy);

	suffix = find_suffix (copy);
	unit = parse_unit_suffix (suffix, unit);
	suffix[0] = 0;

	if (sscanf (copy, "%lf", &num) != 1) {
		ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Invalid number."));
		goto error_free_copy;
	}

	unit_size = ped_unit_get_size (dev, unit);
	radius = ped_div_round_up (unit_size, dev->sector_size) - 1;
	if (radius < 0)
		radius = 0;

	*sector = num * unit_size / dev->sector_size;
	/* negative numbers count from the end */
	if (copy[0] == '-')
		*sector += dev->length;
	if (range) {
		*range = geometry_from_centre_radius (dev, *sector, radius);
		if (!*range) {
			ped_exception_throw (
				PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("The location %s is outside of the "
				  "device %s."),
				str, dev->path);
			goto error_free_copy;
		}
	}
	*sector = clip (dev, *sector);

	ped_free (copy);
	return 1;

error_free_copy:
	ped_free (copy);
error:
	*sector = 0;
	if (range)
		*range = NULL;
	return 0;
}


/** @} */
