/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2000, 2001, 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
*/

/**
 * \addtogroup PedConstraint
 *
 * \brief Constraint solver interface. 
 * 
 * Constraints are used to communicate restrictions on operations Constraints
 * are restrictions on the location and alignment of the start and end of a
 * partition, and the minimum and maximum size.
 *
 * Constraints are closed under intersection (for the proof see the source
 * code).  For background information see the Chinese Remainder Theorem.
 *
 * This interface consists of construction constraints, finding the intersection
 * of constraints, and finding solutions to constraints.
 *
 * The constraint solver allows you to specify constraints on where a partition
 * or file system (or any PedGeometry) may be placed/resized/etc. For example,
 * you might want to make sure that a file system is at least 10 Gb, or that it
 * starts at the beginning of new cylinder.
 *
 * The constraint solver in this file unifies solver in geom.c (which allows you
 * to specify constraints on ranges) and natmath.c (which allows you to specify
 * alignment constraints).
 *
 * @{
 */

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

/**
 * Initializes a pre-allocated piece of memory to contain a constraint
 * with the supplied default values.
 *
 * \return \c 0 on failure.
 */
int
ped_constraint_init (
	PedConstraint* constraint,
	const PedAlignment* start_align,
	const PedAlignment* end_align,
	const PedGeometry* start_range,
	const PedGeometry* end_range,
	PedSector min_size,
	PedSector max_size)
{
	PED_ASSERT (constraint != NULL, return 0);
	PED_ASSERT (start_range != NULL, return 0);
	PED_ASSERT (end_range != NULL, return 0);
	PED_ASSERT (min_size > 0, return 0);
	PED_ASSERT (max_size > 0, return 0);

	constraint->start_align = ped_alignment_duplicate (start_align);
	constraint->end_align = ped_alignment_duplicate (end_align);
	constraint->start_range = ped_geometry_duplicate (start_range);
	constraint->end_range = ped_geometry_duplicate (end_range);
	constraint->min_size = min_size;
	constraint->max_size = max_size;

	return 1;
}

/**
 * Convenience wrapper for ped_constraint_init().
 *
 * Allocates a new piece of memory and initializes the constraint.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_new (
	const PedAlignment* start_align,
	const PedAlignment* end_align,
	const PedGeometry* start_range,
	const PedGeometry* end_range,
	PedSector min_size,
	PedSector max_size)
{
	PedConstraint*	constraint;

	constraint = (PedConstraint*) ped_malloc (sizeof (PedConstraint));
	if (!constraint)
		goto error;
	if (!ped_constraint_init (constraint, start_align, end_align,
			          start_range, end_range, min_size, max_size))
		goto error_free_constraint;
	return constraint;

error_free_constraint:
	ped_free (constraint);
error:
	return NULL;
}

/**
 * Return a constraint that requires a region to be entirely contained inside
 * \p max, and to entirely contain \p min.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_new_from_min_max (
	const PedGeometry* min,
	const PedGeometry* max)
{
	PedGeometry	start_range;
	PedGeometry	end_range;

	PED_ASSERT (min != NULL, return NULL);
	PED_ASSERT (max != NULL, return NULL);
	PED_ASSERT (ped_geometry_test_inside (max, min), return NULL);

	ped_geometry_init (&start_range, min->dev, max->start,
			   min->start - max->start + 1);
	ped_geometry_init (&end_range, min->dev, min->end,
			   max->end - min->end + 1);

	return ped_constraint_new (
			ped_alignment_any, ped_alignment_any,
			&start_range, &end_range,
			min->length, max->length);
}

/**
 * Return a constraint that requires a region to entirely contain \p min.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_new_from_min (const PedGeometry* min)
{
	PedGeometry	full_dev;

	PED_ASSERT (min != NULL, return NULL);

	ped_geometry_init (&full_dev, min->dev, 0, min->dev->length);
	return ped_constraint_new_from_min_max (min, &full_dev);
}

/**
 * Return a constraint that requires a region to be entirely contained inside
 * \p max.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_new_from_max (const PedGeometry* max)
{
	PED_ASSERT (max != NULL, return NULL);

	return ped_constraint_new (
			ped_alignment_any, ped_alignment_any,
			max, max, 1, max->length);
}

/**
 * Duplicate a constraint.
 *
 * \return \c NULL on failure.
 */
PedConstraint*
ped_constraint_duplicate (const PedConstraint* constraint)
{
	PED_ASSERT (constraint != NULL, return NULL);

	return ped_constraint_new (
		constraint->start_align,
		constraint->end_align,
		constraint->start_range,
		constraint->end_range,
		constraint->min_size,
		constraint->max_size);
}

/**
 * Return a constraint that requires a region to satisfy both \p a and \p b.
 *
 * Moreover, any region satisfying \p a and \p b will also satisfy the returned
 * constraint.
 *
 * \return \c NULL if no solution could be found (note that \c NULL is a valid
 *         PedConstraint).
 */
PedConstraint*
ped_constraint_intersect (const PedConstraint* a, const PedConstraint* b)
{
	PedAlignment*	start_align;
	PedAlignment*	end_align;
	PedGeometry*	start_range;
	PedGeometry*	end_range;
	PedSector	min_size;
	PedSector	max_size;
	PedConstraint*	constraint;

	if (!a || !b)
		return NULL;

	start_align = ped_alignment_intersect (a->start_align, b->start_align);
	if (!start_align)
		goto empty;
	end_align = ped_alignment_intersect (a->end_align, b->end_align);
	if (!end_align)
		goto empty_destroy_start_align;
	start_range = ped_geometry_intersect (a->start_range, b->start_range);
	if (!start_range)
		goto empty_destroy_end_align;
	end_range = ped_geometry_intersect (a->end_range, b->end_range);
	if (!end_range)
		goto empty_destroy_start_range;
	min_size = PED_MAX (a->min_size, b->min_size);
	max_size = PED_MIN (a->max_size, b->max_size);

	constraint = ped_constraint_new (
			start_align, end_align, start_range, end_range,
			min_size, max_size);
	if (!constraint)
		goto empty_destroy_end_range;

	ped_alignment_destroy (start_align);
	ped_alignment_destroy (end_align);
	ped_geometry_destroy (start_range);
	ped_geometry_destroy (end_range);
	return constraint;

empty_destroy_end_range:
	ped_geometry_destroy (end_range);
empty_destroy_start_range:
	ped_geometry_destroy (start_range);
empty_destroy_end_align:
	ped_alignment_destroy (end_align);
empty_destroy_start_align:
	ped_alignment_destroy (start_align);
empty:
	return NULL;
}

/**
 * Release the memory allocated for a PedConstraint constructed with
 * ped_constraint_init().
 */
void
ped_constraint_done (PedConstraint* constraint)
{
	PED_ASSERT (constraint != NULL, return);

	ped_alignment_destroy (constraint->start_align);
	ped_alignment_destroy (constraint->end_align);
	ped_geometry_destroy (constraint->start_range);
	ped_geometry_destroy (constraint->end_range);
}

/**
 * Release the memory allocated for a PedConstraint constructed with
 * ped_constraint_new().
 */
void
ped_constraint_destroy (PedConstraint* constraint)
{
	if (constraint) {
		ped_constraint_done (constraint);
		ped_free (constraint);
	}
}

/*
 * Return the region within which the start must lie
 * in order to satisfy a constriant.  It takes into account
 * constraint->start_range, constraint->min_size and constraint->max_size.
 * All sectors in this range that also satisfy alignment requirements have
 * an end, such that the (start, end) satisfy the constraint.
 */
static PedGeometry*
_constraint_get_canonical_start_range (const PedConstraint* constraint)
{
	PedSector	first_end_soln;
	PedSector	last_end_soln;
	PedSector	min_start;
	PedSector	max_start;
	PedGeometry	start_min_max_range;

	if (constraint->min_size > constraint->max_size)
		return NULL;

	first_end_soln = ped_alignment_align_down (
			constraint->end_align, constraint->end_range,
			constraint->end_range->start);
	last_end_soln = ped_alignment_align_up (
			constraint->end_align, constraint->end_range,
			constraint->end_range->end);
	if (first_end_soln == -1 || last_end_soln == -1
	    || first_end_soln > last_end_soln
	    || last_end_soln < constraint->min_size)
		return NULL;

	min_start = first_end_soln - constraint->max_size + 1;
	if (min_start < 0)
		min_start = 0;
	max_start = last_end_soln - constraint->min_size + 1;
	if (max_start < 0)
		return NULL;

	ped_geometry_init (
		&start_min_max_range, constraint->start_range->dev,
		min_start, max_start - min_start + 1);

	return ped_geometry_intersect (&start_min_max_range,
				       constraint->start_range);
}

/*
 * Return the nearest start that will have at least one other end that
 * together satisfy the constraint.
 */
static PedSector
_constraint_get_nearest_start_soln (const PedConstraint* constraint,
				    PedSector start)
{
	PedGeometry*	start_range;
	PedSector	result;

	start_range = _constraint_get_canonical_start_range (constraint);
	if (!start_range)
		return -1;
	result = ped_alignment_align_nearest (
			constraint->start_align, start_range, start);
	ped_geometry_destroy (start_range);
	return result;
}

/*
 * Given a constraint and a start ("half of the solution"), find the
 * range of all possible ends, such that all (start, end) are solutions
 * to constraint (subject to additional alignment requirements).
 */
static PedGeometry*
_constraint_get_end_range (const PedConstraint* constraint, PedSector start)
{
	PedDevice*	dev = constraint->end_range->dev;
	PedSector	first_min_max_end;
	PedSector	last_min_max_end;
	PedGeometry	end_min_max_range;

	if (start + constraint->min_size - 1 > dev->length - 1)
		return NULL;

	first_min_max_end = start + constraint->min_size - 1;
	last_min_max_end = start + constraint->max_size - 1;
	if (last_min_max_end > dev->length - 1)
		last_min_max_end = dev->length - 1;

	ped_geometry_init (&end_min_max_range, dev,
			   first_min_max_end,
			   last_min_max_end - first_min_max_end + 1);

	return ped_geometry_intersect (&end_min_max_range,
		       		       constraint->end_range);
}

/*
 * Given "constraint" and "start", find the end that is nearest to
 * "end", such that ("start", the end) together form a solution to
 * "constraint".
 */
static PedSector
_constraint_get_nearest_end_soln (const PedConstraint* constraint,
				  PedSector start, PedSector end)
{
	PedGeometry*	end_range;
	PedSector	result;

	end_range = _constraint_get_end_range (constraint, start);
	if (!end_range)
		return -1;

	result = ped_alignment_align_nearest (constraint->end_align, end_range,
		       			      end);
	ped_geometry_destroy (end_range);
	return result;
}

/**
 * Return the nearest region to \p geom that satisfy a \p constraint.
 * 
 * Note that "nearest" is somewhat ambiguous.  This function makes
 * no guarantees about how this ambiguity is resovled.
 *
 * \return PedGeometry, or NULL when a \p constrain cannot be satisfied
 */
PedGeometry*
ped_constraint_solve_nearest (
	const PedConstraint* constraint, const PedGeometry* geom)
{
	PedSector	start;
	PedSector	end;
	PedGeometry*	result;

	if (constraint == NULL)
		return NULL;

	PED_ASSERT (geom != NULL, return NULL);
	PED_ASSERT (constraint->start_range->dev == geom->dev, return NULL);

	start = _constraint_get_nearest_start_soln (constraint, geom->start);
	if (start == -1)
		return NULL;
	end = _constraint_get_nearest_end_soln (constraint, start, geom->end);
	if (end == -1)
		return NULL;

	result = ped_geometry_new (geom->dev, start, end - start + 1);
	if (!result)
		return NULL;
	PED_ASSERT (ped_constraint_is_solution (constraint, result),
		    return NULL);
	return result;
}

/**
 * Find the largest region that satisfies a constraint.
 * 
 * There might be more than one solution.  This function makes no
 * guarantees about which solution it will choose in this case.
 */
PedGeometry*
ped_constraint_solve_max (const PedConstraint* constraint)
{
	PedDevice*	dev;
	PedGeometry	full_dev;

	if (!constraint)
		return NULL;
	dev = constraint->start_range->dev;
	ped_geometry_init (&full_dev, dev, 0, dev->length - 1);
	return ped_constraint_solve_nearest (constraint, &full_dev);
}

/**
 * Check whether \p geom satisfies the given constraint.
 *
 * \return \c 1 if it does.
 **/
int
ped_constraint_is_solution (const PedConstraint* constraint,
	       		    const PedGeometry* geom)
{
	PED_ASSERT (constraint != NULL, return 0);
	PED_ASSERT (geom != NULL, return 0);

	if (!ped_alignment_is_aligned (constraint->start_align, NULL,
				       geom->start))
		return 0;
	if (!ped_alignment_is_aligned (constraint->end_align, NULL, geom->end))
		return 0;
	if (!ped_geometry_test_sector_inside (constraint->start_range,
					      geom->start))
		return 0;
	if (!ped_geometry_test_sector_inside (constraint->end_range, geom->end))
		return 0;
	if (geom->length < constraint->min_size)
		return 0;
	if (geom->length > constraint->max_size)
		return 0;
	return 1;
}

/**
 * Return a constraint that any region on the given device will satisfy.
 */
PedConstraint*
ped_constraint_any (const PedDevice* dev)
{
	PedGeometry	full_dev;

	if (!ped_geometry_init (&full_dev, dev, 0, dev->length))
		return NULL;

	return ped_constraint_new (
			ped_alignment_any,
		       	ped_alignment_any,
			&full_dev,
			&full_dev,
		       	1,
			dev->length);
}

/**
 * Return a constraint that only the given region will satisfy.
 */
PedConstraint*
ped_constraint_exact (const PedGeometry* geom)
{
	PedAlignment	start_align;
	PedAlignment	end_align;
	PedGeometry	start_sector;
	PedGeometry	end_sector;

	ped_alignment_init (&start_align, geom->start, 0);
	ped_alignment_init (&end_align, geom->end, 0);
	ped_geometry_init (&start_sector, geom->dev, geom->start, 1);
	ped_geometry_init (&end_sector, geom->dev, geom->end, 1);

	return ped_constraint_new (&start_align, &end_align,
				   &start_sector, &end_sector, 1,
				   geom->dev->length);
}

/**
 * @}
 */

