#!/bin/sh

. /lib/partman/definitions.sh
. /lib/partman/recipes.sh

dev=$1
free_space=$2
recipe=$3

# Let us be safe and update the directories
update_all

cd $dev
open_dialog PARTITION_INFO $free_space
read_line x1 x2 free_size free_type x3 x4 x5
close_dialog

free_size=$(expr 0000000"$free_size" : '0*\(..*\)......$') # convert to megabytes

if [ "$free_type" = unusable ]; then
    db_input critical partman-auto/unusable_space || true
    db_go || true
    exit 1
fi

db_progress START 0 6 partman-auto/text/automatically_partition
db_progress INFO partman-auto/progress/info

decode_recipe $recipe

db_progress STEP 1

# Make factors small numbers so we can multiply on them.
# Also ensure that fact, max and fs are valid
# (Ofcourse in valid recipes they must be valid.)
factsum=$(($(factor_sum) - $(min_size)))
scheme=$(
    foreach_partition '
        local min fact max fs
        min=$1
	fact=$((($2 - $min) * 100 / $factsum))
	max=$3
	fs=$4
        case "$fs" in
	    ext2|ext3|linux-swap|fat16|fat32|hfs)
		true
		;;
	    *)
		fs=ext2
		;;
        esac
	shift; shift; shift; shift
	echo $min $fact $max $fs $*'
)

db_progress STEP 1

oldscheme=''
while [ "$scheme" != "$oldscheme" ]; do
    oldscheme="$scheme"
    factsum=$(factor_sum)
    unallocated=$(($free_size - $(min_size)))
    if [ $unallocated -lt 0 ]; then
	unallocated=0
    fi
    scheme=$(
	foreach_partition '
	    local min fact max newmin
	    min=$1
	    fact=$2
	    max=$3
	    shift; shift; shift
	    newmin=$(($min + $unallocated * $fact / $factsum))
	    if [ $newmin -le $max ]; then
		echo $newmin $fact $max $*
	    else
		echo $max 0 $max $*
	    fi'
    )
done

db_progress STEP 1

for device in $DEVICES/*; do
    [ -d "$device" ] || continue
    cd $device
    open_dialog PARTITIONS
    while { read_line num id size type fs path name; [ "$id" ]; }; do
	if [ -f $id/method ]; then
	    rm $id/method
	fi
    done
    close_dialog
done

db_progress STEP 1

cd $dev

while
    [ "$free_type" = pri/log ] \
    && echo $scheme | grep '\$primary{' >/dev/null
do
    pull_primary
    set -- $primary
    open_dialog NEW_PARTITION primary $4 $free_space beginning ${1}000001
    read_line num id size type fs path name
    close_dialog
    if [ -z "$id" ]; then
	db_progress STOP
	autopartitioning_failed
    fi
    neighbour=$(partition_after $id)
    if [ "$neighbour" ]; then
	open_dialog PARTITION_INFO $neighbour
	read_line x1 new_free_space x2 new_free_type fs x3 x4
	close_dialog
    fi
    if 
	[ -z "$neighbour" -o "$fs" != free \
	  -o "$new_free_type" = primary -o "$new_free_type" = unusable ]
    then
	open_dialog DELETE_PARTITION $id
	close_dialog
	open_dialog NEW_PARTITION primary $4 $free_space end ${1}000001
	read_line num id size type fs path name
	close_dialog
	if [ -z "$id" ]; then
	    db_progress STOP
	    autopartitioning_failed
	fi
	neighbour=$(partition_before $id)
	if [ "$neighbour" ]; then
	    open_dialog PARTITION_INFO $neighbour
	    read_line x1 new_free_space x2 new_free_type fs x3 x4
	    close_dialog
	fi
	if 
	    [ -z "$neighbour" -o "$fs" != free -o "$new_free_type" = unusable ]
	then
	    open_dialog DELETE_PARTITION $id
	    close_dialog
	    break
	fi
    fi
    shift; shift; shift; shift
    setup_partition $id $*
    primary=''
    scheme="$logical"
    free_space=$new_free_space
    free_type="$new_free_type"
done

db_progress STEP 1

foreach_partition '
    if [ -z "$free_space" ]; then
        db_progress STOP
	autopartitioning_failed
    fi
    open_dialog PARTITION_INFO $free_space
    read_line x1 free_space x2 free_type fs x3 x4
    close_dialog
    if [ "$fs" != free ]; then
        free_type=unusable
    fi
    case "$free_type" in
	primary|logical)
	    type="$free_type"
	    ;;
	pri/log)
	    type=logical
	    ;;
	unusable)
            db_progress STOP
	    autopartitioning_failed
	    ;;
    esac
    if [ "$last" = yes ]; then
        open_dialog NEW_PARTITION $type $4 $free_space full ${1}000001
    else
        open_dialog NEW_PARTITION $type $4 $free_space beginning ${1}000001
    fi
    read_line num id size type fs path name
    close_dialog
    if [ -z "$id" ]; then
        db_progress STOP
	autopartitioning_failed
    fi
    shift; shift; shift; shift
    setup_partition $id $*
    free_space=$(partition_after $id)'

db_progress STEP 1

update_all

db_progress STOP
