#!/bin/sh

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

dev=$1

# copy/paste from partman-auto/autopartition to scratch the disk

[ -f $dev/size ] || exit 1
free_size=$(cat $dev/size)
free_size=$(expr 0000000"$free_size" : '0*\(..*\)......$') # convert to megabytes

# we need to be sure we can perform the selected receipe and be able to add /boot.
# virtually remove 200Mb from the free space. Perhaps a reiteration over the recipe
# would be more accurate, but for now this is more than fine.
free_size=$(expr $free_size - 200)

choose_recipe "$free_size" || exit $?

cd $dev

open_dialog LABEL_TYPES
types=$(read_list)
close_dialog

label_type=$(default_disk_label)

if ! expr "$types" : ".*${label_type}.*" >/dev/null; then
        label_type=msdos # most widely used
fi

if [ "$label_type" = sun ]; then
        db_input critical partman/confirm_write_new_label
        db_go || exit 0
        db_get partman/confirm_write_new_label
        if [ "$RET" = false ]; then
                db_reset partman/confirm_write_new_label
                exit 1
        fi
        db_reset partman/confirm_write_new_label
fi

open_dialog NEW_LABEL "$label_type"
close_dialog

if [ "$label_type" = sun ]; then
        # write the partition table to the disk
        disable_swap
        open_dialog COMMIT
        close_dialog
        sync
        # reread it from there
        open_dialog UNDO
        close_dialog
        enable_swap
fi

# Different types partition tables support different visuals.  Some
# have partition names other don't have, some have extended and
# logical partitions, others don't.  Hence we have to regenerate the
# list of the visuals
if [ -f visuals ]; then
        rm visuals
fi

modprobe dm-mod  >>/var/log/messages 2>&1 || true
modprobe lvm-mod  >>/var/log/messages 2>&1 || true

### now we need to create the /boot + lvm envelope

# just to be sure
update_all

decode_recipe $recipe

# get the free_size free_space infos from the device again

cd $dev
open_dialog PARTITIONS
read_line num id size type fs path name
close_dialog
free_space="$id"
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

# make a backup of the original scheme that we will use inside the VG
# this operation is tricky because it should consider some special arches like ppc
# that needs some extra partitions to work properly. For now let's make it simple
# and generic.
backupscheme="$scheme"

# now we need to create the /boot and the pv/vg scheme

# if the original scheme has /boot, let's use that instead of a fake otherwise we add it to a 256Mb default.
if echo $scheme | grep -eq "[[:space:]]/boot[[:space:]]"; then
    backupscheme=$(echo "$backupscheme" | grep -v "[[:space:]]/boot[[:space:]]")
    bootscheme=$(echo "$backupscheme" | grep "[[:space:]]/boot[[:space:]]")
    # we need to create a new recipe here, stripped of /boot
else
    bootscheme="128 512 256 ext3 \$primary{ } \$bootable{ } method{ format } format{ } use_filesystem{ } filesystem{ ext3 } mountpoint{ /boot }"
    # original recipe needs no changing. Only proper recalculation in perform_recipe_by_lvm that's done automatically.
fi
# creating envelope
scheme="$bootscheme${NL}100 1000 1000000000 ext3 method { lvm }"

expand_scheme

clean_method

### here we need to create /boot and the partition that will become our pv/vg ###

## copy/paste from partman-auto/perform_recipe

# the while is supposed to create all the primary partitions. We only have one but
# for the sake of avoiding mistakes the entire block of code is copied.

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
        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
            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

### this one creates all the logical partitions and adds them to the vg

devfspv_devices=''
foreach_partition '
    if [ -z "$free_space" ]; then
        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)
            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
        autopartitioning_failed
    fi
    devfspv_devices="$devfspv_devices $path"
    # make the partition LVM
    open_dialog GET_FLAGS $id
    flags=$(read_paragraph)
    close_dialog
    open_dialog SET_FLAGS $id
    write_line "$flags"
    write_line lvm
    write_line NO_MORE
    close_dialog
    shift; shift; shift; shift
    setup_partition $id $*
    free_space=$(partition_after $id)'

# write the partition tables
disable_swap
cd $dev
open_dialog COMMIT
close_dialog

update_all

#### now we have the container! yeppa!!! ####

if type udevstart >/dev/null 2>&1; then
    udevstart
fi

for pv in $devfspv_devices; do
    realpath="$(mapdevfs "$pv")"
    pv_devices="$pv_devices $realpath"
done

# Choose name, create VG and attach each partition as a physical volume
noninteractive=true
while true; do
    db_input medium partman-auto-lvm/new_vg_name || eval $noninteractive
    db_go || exit 1
    db_get partman-auto-lvm/new_vg_name
    VG_name="$RET"

    if VG_create "$VG_name" $pv_devices; then break; fi
    noninteractive="exit 1"
done

perform_recipe_by_lvm $VG_name $recipe

# default to accepting the autopartitioning
menudir_default_choice /lib/partman/choose_partition finish finish || true
