#!/bin/sh -e

. /usr/share/debconf/confmodule
. /lib/preseed/preseed.sh # for $logfile
. /lib/debian-edu-common

log() {
    logger -t debian-edu-profile "info: $*"
}

error() {
    logger -t debian-edu-profile "error: $*"
}

add_preseed() {
    owner="$1"
    template="$2"
    type="$3"
    value="$4"
    echo $owner $template $type "$value" >> $preseedfile
}

ask_can_we_erase_harddrive() {
    # ask if the user want to repartition the hard drives
    # automaticaly, if not we will skip to manual mode
    db_settitle debian-edu-install/confirm/title
    db_input critical "debian-edu-install/confirm" || true
    db_go || true
    db_get "debian-edu-install/confirm" || true
    AUTOPARTITIONING="$RET"
    if test "$RET" = true ; then
        log "User accepted wiping out the harddrive"
    else
        log "User refused wiping out the harddrive, enabling manual partitioning"
    fi
}

ask_about_popcon() {
    #ask and preseed popcon here to save the need to monitor the install
    RET=""
    db_settitle debian-edu-install/participate-popcon/title
    db_input critical "debian-edu-install/participate-popcon" || true
    log "do we want popcon?"
    db_go || true
    db_get "debian-edu-install/participate-popcon" || true
    if test "$RET" = true ; then
	add_preseed popularity-contest popularity-contest/participate boolean true
	log "popcon: yes!"
    elif test "$RET" = false ; then
	add_preseed popularity-contest popularity-contest/participate boolean false
	log "popcon: no!"
    fi
}

check_profiles() {
    preseed=
    #if a value is unset it breaks the case esac later on
    workstation=false
    roaming=false
    ltspserver=false
    server=false
    networked=false
    standalone=false
    minimal=false

    for value in `echo $EDUPROFILE |sed 's/ /-/g' | sed 's/,-/ /g'`; do
	case $value in
	    Workstation)
		networked=true
		workstation=true
		log "Added task '$value'"
		;;
	    Roaming-Workstation)
		# Partition as Standalone, preseed as workstation
		networked=true
		workstation=true
		roaming=true
		if test "$server" = true ; then
		    error=true
		else
		    error=
		fi
		log "Added task '$value'"
		;;
	    LTSP-Server)
		networked=true
		workstation=true
		ltspserver=true
		log "Added task '$value'"
		;;
	    Main-Server|Server)
		networked=true
		server=true
		log "Added task '$value'"
		;;
	    Standalone)
		standalone=true
		if test "$networked" = true ; then
		    error=true
		else
		    error=
		fi
		log "Added task '$value'"
		;;
	    Minimal)
		networked=true
		minimal=true
		log "Added task '$value'"
		;;
	    *)
		error "unknown profile '$value'"
		;;
	esac
    done
}

# Return the number of non-wireless network interfaces
non_wifi_iface_count() {
    count=0
    for iface in $(ip -o link | grep '^.: eth'|cut -d: -f2) ; do
	if [ -d /sys/class/net/$iface/wireless ] ; then
	    :
	else
	    count=$(($count + 1))
	fi
    done
    echo $count
}

AUTOPARTITIONING=false

#Detect debian-edu-expert mode
#Treat an expert install as a debian-edu-expert mode
if grep -iq debian-edu-expert /proc/cmdline ; then
   expert=true
elif grep -iq 'priority=low' /proc/cmdline ; then
   expert=true
else
   expert=false
fi

template="debian-edu-install/profile"

preseedfile=/tmp/debian-edu-preseed.$$
touch $preseedfile

# Preselect based on what we can detect from the environment.  If no
# main-server is found, select main-server for non-laptops and
# standalone for laptops.  If a main-server is detected select
# workstation for non-laptops, and roaming-workstation for laptops.
# If more than one network interface is detected, preselect
# LTSP-Server for non-laptops.
if wget http://tjener/debian-edu-install.dat > /dev/null 2>&1 ; then
    log "main-server detected on the network"
    if laptop-detect ; then
	log "laptop detected, preselecting roaming workstation"
	defaultprofile="Roaming-Workstation"
	laptop=true
    else
	defaultprofile="Workstation"
    fi
else
    log "main-server not detected on the network"
    if laptop-detect ; then
	log "laptop detected, preselecting standalone"
	defaultprofile="Standalone"
	laptop=true
    else
	defaultprofile="Main-Server, LTSP-Server, Workstation"
	mainserver=true
    fi
fi

if [ true != "$mainserver" ] && [ true != "$laptop" ] \
    && [ 1 -lt $(non_wifi_iface_count) ] ; then
    log "several network cards detected, preselecting ltsp-server"
    defaultprofile="$defaultprofile, LTSP-Server"
fi

log "choosing profile"

# Do not load our default if the value was preseeded
if db_fget "$template" seen && [ "$RET" = "false" ]; then
    log "Setting default profile to $defaultprofile"
    db_set "$template" "$defaultprofile"
fi

#ask profile question
log "Debian-edu-expert = $expert"

RET=""
looplimit="xxx"
loopcount=""

while test -z "$RET" ; do
    db_input critical "$template"  || [ $? -eq 30 ]
    db_go || true
    db_fset "$template" seen false || true

    db_get "$template" || true
    loopcount="x$loopcount"
    if test "$loopcount" = "$looplimit" ; then
	exit 1;
    fi
done
EDUPROFILE=$RET
log "full profile is '$EDUPROFILE' loopcount='$loopcount'"


check_profiles

while test -n "$error" ; do
	db_fset "debian-edu-install/standalone_only" seen false || true
	db_input critical "debian-edu-install/standalone_only" || true
	log "Wrong selection in combination with Standalone"
	db_go || true
	if test "$expert" = true ; then
		template="debian-edu-install/profile-expert"
	else
		template"debian-edu-install/profile"
	fi
	db_fset "$template" seen false || true
    	db_input critical "$template"  || [ $? -eq 30 ]
    	db_go || true

    	db_get "$template" || true
    	loopcount="x$loopcount"
    	if test "$loopcount" = "$looplimit" ; then
    	    exit 1;
    	fi
	if test -z "$RET" ; then
		continue;
	fi
	EDUPROFILE=$RET
	log "full profile is '$EDUPROFILE' loopcount='$loopcount'"
	check_profiles
done

# Make sure the default values have this priority, with lower number
# priority overriding higher number
#  1 main-server
#  2 ltsp-server
#  3 workstation
#  4 networked (Common for non-standalone)
#  5 standalone
#  6 common

preseeds="common"

if test "$standalone" = true ; then
    preseeds="$preseeds standalone"
fi
if test "$networked" = true ; then
    preseeds="$preseeds networked"
fi
if test "$workstation" = true ; then
    preseeds="$preseeds workstation"
fi
if test "$ltspserver" = true ; then
    preseeds="$preseeds ltsp-server"
fi
if test "$server" = true ; then
    preseeds="$preseeds main-server"
fi

#
# Select partitioning template (partman recipe), based on which
# profile is selected
#

#use first available disk no matter what ?

automatic_partitioning() {
    log "Using automatic_partitioning"
    arch=$(/bin/archdetect | cut -d"/" -f1)
    subarch=$(/bin/archdetect | cut -d"/" -f2)
    log "Detected arch : $arch"
    log "Detected subarch : $subarch"

    case "$arch-$subarch" in
	    "i386-generic") #unset both use the default
		arch=
		subarch=
	;;
	    "powerpc-powermac_newworld") #set
	    	arch=-powerpc
		subarch=-powermac_newworld
	;;
	    "powerpc-prep") #set
	    	arch=-powerpc
		subarch=-prep
	;;
	    *)	#just in case
		arch=
		subarch=
	;;
    esac

    case "$server-$workstation-$ltspserver-$standalone-$minimal-$roaming" in
    "true-false-false-false-false-false") # single main server
        log "Preseeding partman for Single Main-server"
        db_set "partman-auto/choose_recipe" Debian-Edu Main-Server
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/90edumain
        ;;
    "false-true-true-false-false-false") # single ltspserver
        log "Preseeding partman for Single LTSP-Server"
        db_set "partman-auto/choose_recipe" Debian-Edu LTSP-Server
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/94edultsp

        # Configure the enable-nat script from debian-edu-config to
        # enable NAT on LTSP-Servers but not on Combi-Servers
        add_preseed debian-edu-config debian-edu-config/enable-nat boolean true
        ;;
    "false-true-false-false-false-false") # single workstation
        log "Preseeding partman for Single Workstation"
        db_set "partman-auto/choose_recipe" Debian-Edu Workstation
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/96eduwork
        ;;
    "false-true-false-false-false-true") # roaming workstatoin
        log "Preseeding partman for Single Roaming Workstation, select 98edustandalone recipe as default."
        db_set "partman-auto/choose_recipe" Debian-Edu Standalone
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/98edustandalone
        ;;
    "true-false-true-false-false-false") #mainserver & ltspserver
        log "Preseeding partman for Combo Main-server and LTSP-Server"
        db_set "partman-auto/choose_recipe" Debian-Edu Main-Server and LTSP-Server
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/91edumain+ltsp

        # Configure slbackup here in case we have a combo server installation
        add_preseed slbackup slbackup/client_location string "/etc /skole/tjener/home0 /opt/ltsp/i386/etc /var/backups"
        ;;
    "true-true-false-false-false-false") # mainserver & workstation
        log "Preseeding partman for Combo Main-Server and Workstation"
        db_set "partman-auto/choose_recipe" Debian-Edu Main-Server and Workstation
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/92edumain+ws
        ;;
    "true-true-true-false-false-false") # mainserver & ltspserver & workstation
        log "Preseeding partman for Combo Main-server, LTSP-Server, and workstation"
        db_set "partman-auto/choose_recipe" Debian-Edu Main-Server and LTSP-Server
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/91edumain+ltsp

        ;;
    "false-false-false-true-false-false") # standalone
        log "Preseeding partman for Single Standalone, select 98edustandalone recipe as default."
        db_set "partman-auto/choose_recipe" Debian-Edu Standalone
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/98edustandalone
        ;;
    "false-false-false-false-true-false") # minimal
        log "Preseeding partman for Minimal"
        db_set "partman-auto/choose_recipe" Debian-Edu Minimal
        db_set "partman-auto/expert_recipe_file" /lib/partman/recipes$arch$subarch/97minimal
        ;;
   esac

   # set recipe selection to seen
   db_fset "partman-auto/choose_recipe" seen true || true
   db_set "partman-auto-lvm/new_vg_name" vg_system

   # we dont want to see this
   db_set "partman/choose_partition" "Finish partitioning and write changes to disk"
   db_fset "partman/choose_partition" seen true || true

   # use first available disk
   # Disable in order to not lock up the installer, untill it's
   # reliable [Ronny Aasen 20080201]
   #db_set "partman-auto/disk" /dev/discs/disc0/disc
   #and method lvm
   db_set "partman-auto/method" lvm
   db_fset "partman-auto/method" seen true || true

   # This question is asked when there are more than one disk found.
   # Ensure the correct answer is set.
   db_set "partman-auto/init_automatically_partition" "60some_device_lvm__________lvm"
   db_fset "partman-auto/init_automatically_partition" seen true || true

   add_preseed partman-lvm partman-lvm/confirm boolean true
   add_preseed partman-lvm partman-lvm/confirm_nooverwrite boolean true

   # we do not want to see the confirm write to disk, or the purge lvm
   # questions. We have asked this already
   add_preseed partman partman/confirm_write_new_label boolean true
   add_preseed partman partman/confirm boolean true
   add_preseed partman partman/confirm_nooverwrite boolean true
   add_preseed partman-lvm partman-lvm/device_remove_lvm boolean true
}

ask_can_we_erase_harddrive

if [ true = "$AUTOPARTITIONING" ] ; then
    automatic_partitioning
fi

ask_about_popcon

# This code need to be executed here and pass the info found on to the
# prebaseconfig script, and not in the prebaseconfig script itself,
# because the CD is unmounted when the prebaseconfig script is running.

# Based on function from base-installer
set_mirror_info () {
    if [ -f /cdrom/.disk/base_installable ]; then
	PROTOCOL=file
	MIRROR=""
	DIRECTORY="/cdrom/"
	db_get cdrom/codename || true
	if [ "$RET" ] ; then
	    SUITE="$RET"
	else
	    SUITE=testing
	    error "Unable to find CD suite name"
	fi
    else
	mirror_error=""

	db_get mirror/protocol || mirror_error=1
	PROTOCOL="$RET"

	db_get mirror/$PROTOCOL/hostname || mirror_error=1
	MIRROR="$RET"

	db_get mirror/$PROTOCOL/directory || mirror_error=1
	DIRECTORY="$RET"

	if [ "$mirror_error" = 1 ] || [ -z "$PROTOCOL" ] || [ -z "$MIRROR" ]; then
	    error "Missing mirror settings.  Can not find DISTRIBUTION name."
	    return
	fi
    fi

    if db_get mirror/suite && [ "$RET" ] ; then
	SUITE=$RET
    fi
    # Find the distribution codename
    APTLISTDIR=/var/tmp
    mkdir -p $APTLISTDIR
    if [ file = "$PROTOCOL" ]; then
	path="/cdrom/dists/$SUITE/Release"
	cp $path $APTLISTDIR/tmp 2>/dev/null || nogetrel="$path"
    else
	path="$PROTOCOL://$MIRROR$DIRECTORY/dists/$SUITE/Release"
	wget -q "$path" -O $APTLISTDIR/tmp || nogetrel="$path"
    fi

    if [ "$nogetrel" != "" ]; then
	error "Unable to locate '$nogetrel'.  Can not find DISTRIBUTION name."
	return
    fi

    DISTRIBUTION=`grep ^Codename: $APTLISTDIR/tmp | cut -d' ' -f 2`
    rm $APTLISTDIR/tmp
    db_set mirror/distribution "$DISTRIBUTION"
    log "Setting mirror/distribution to $DISTRIBUTION"
}

load_proxy_conf
set_mirror_info

archstr=$(/bin/archdetect)
if [ -f /cdrom/.disk/cd_type ] && egrep -iq 'dvd|bluray' /cdrom/.disk/cd_type; then
    #disable mirror usage if we install from dvd or the usb sticks
    db_set "apt-setup/use_mirror" false
    db_fset "apt-setup/use_mirror" seen true || true
    log "disabling mirror selection on dvd's"
elif ! log-output wget -U "Wget, Debian Edu d-i $DISTRIBUTION $archstr" -qO - http://deb.debian.org/debian/README && \
    ! log-output wget --no-proxy -U "Wget, Debian Edu d-i $DISTRIBUTION $archstr" -qO - http://deb.debian.org/debian/README ; then
    db_settitle debian-edu-install/no-network/title
    db_input critical "debian-edu-install/no-network" || true
    db_go || true
    exit 1
else
    #Enable mirrors for the rest
    log "We will have net, enable the mirrors"
    db_set "apt-setup/use_mirror" true
    db_fset "apt-setup/use_mirror" seen true || true
fi




log "Preseeding"

if [ "$EDUPROFILE" ] ; then
   log "Preseeding target with '$EDUPROFILE'"
   add_preseed debian-edu-install debian-edu-install/profile multiselect "$EDUPROFILE"
else
   log "No profile to preseed"
fi

# In order to show less questions in the rest of the installation, we
# change debconf/priority to critical if the installer is run in the
# default manner.
# Do not mess with priority if the user have defined a priority in the
# boot arguments.
if grep -iq 'priority' /proc/cmdline ; then
    return 0
else
    # Do not mess with priority if the user runs in expert mode.
    if [ false = "$expert" ] ; then
        # Check if it runs at default value, and bump if it does.
        if db_get debconf/priority && [ "$RET" ] ; then
	    if [ $RET == "high" ] ; then db_set "debconf/priority" "critical"; fi
        fi
    fi
fi


for preseed in $preseeds ; do
    if [ -f /usr/lib/debian-edu-install/defaults.$preseed ] ; then
        log "Found preseeding for '$preseed'"
        cat /usr/lib/debian-edu-install/defaults.$preseed >> $preseedfile
    else
        error "Unable to find preseeding for '$preseed'"
    fi
done

# Enable the firstboot script to report installation errors.  Preseeded
# here and not in defaults.common to make sure it only is set on first time
# installation using debian-installer.  Checking the seen flag to allow
# this setting to be overriden using preseeding.
db_fget debian-edu-install/run-firstboot seen || true
if [ true != "$RET" ] ; then
    add_preseed debian-edu-install debian-edu-install/run-firstboot boolean true
fi

# Load into the cdebconf database used by d-i
debconf-set-selections $preseedfile || \
    error "Failed to load preseed values from $preseedfile"

# Get the post-base-installer.d fragment from preseed to pass relevant
# values into the debconf database in /target when the base system is
# installed.
touch $logfile # Create if missing, to make sure >> work
cat $preseedfile >> $logfile

# rm $preseedfile

# Make sure that the kernel question doesn't show up.  Can not use
# preseeding directly, as these values are not loaded yet when this
# script run.
db_fset "base-installer/kernel/image" seen true || true
db_fset "base-installer/kernel/which-kernel" seen true || true

# Avoid message which sometimes appears with newer x11-common due to
# upgrade issues.  Can not use preseeding directly, as these values
# are not loaded yet when this script run.
db_fset "x11-common/upgrade_issues" seen true || true
