#!/bin/bash 

########################################################################
# MuGLIn - MuGLIn GNU/Linux Installation		                       #
#                                                                      #
# Copyright (C) 2010 Jakob Gurnhofer <jakob.gurnhofer@gmail.com>       #
# Copyricht (C) 2010 Srdjan Markovic <smark2ki@htl.moedling.at>        #
#                                                                      #
# This file is part of MuGLIn source code.                             #
#                                                                      #
# MuGLIn 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 3 of the License, or    #
# (at your option) any later version.                                  #
#                                                                      #
# MuGLIn 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 MuGLIn. If not, see <http://www.gnu.org/licenses/>.       #
########################################################################

. /muglin/functions
grep="/bin/grep"
cat="/bin/cat"
mount="/bin/mount"
head="/usr/bin/head"
tail="/usr/bin/tail"
cut="/usr/bin/cut"
mkdir="/bin/mkdir"

if [ "$1" = "debug" ]; then
	set -xv
	shift
fi

# default mkfs. option:
DMKFSOPT[ext3]=""
DMKFSOPT[vfat]="-F 32"
DMKFSOPT[ext2]=""

#only for developing purposes, will become $1
UAPRE=$1

# fdisk's inputfile
CMDFILE="/tmp/fdisk.cmd"

#number of main loops...			
DISCS=`$grep "Disk:" $UAPRE | wc -l`

#and here we go :)
for (( k=1; k <= $DISCS; k++ )); do
  
  DISC=`$grep "Disk:" $UAPRE | $head -n$k | $tail -n1 | $cut -d":" -f2`
  output d ">Processing $DISC..."
  parts=1
  # workaround because d-i's blackbox can't handle a $grep -A
  zeilenr=`$grep -n $DISC $UAPRE | $cut -d":" -f1`
  zeile=`$head -n$(($zeilenr+1)) $UAPRE | $tail -n1` 
  pcnt=0
  output d -n ">>Parsing unattend.pre..."
  while [ "$zeile" != "" ]; do
    # The following line should handle a missing newline, but may break things
    if [ "$zeile" = "$oldzeile" ]; then break; fi
    part=`echo "$zeile" | $cut -d":" -f1`
    btype[$part]=`echo "$zeile" | $cut -d":" -f2`
    # now it becomes funny, bios partitions has a lot of rules
    # 1. there are three types, Primary, Extended, Logical
    if [ "`echo 'p e l x' | $grep -o ${btype[$part]}`" = "" ]; then
      die "unknown btype";
    fi
    # 2. you cant have more than 4 partitions (except logical)
    if test "${btype[$part]}" = "p" -o "${btype[$part]}" = "e"; then
      pcnt=$(($pcnt+1))
    fi
    if [ $pcnt -gt 4 ];then
	die "Too much partitions,leaving"
    fi
    # sum(sizeof(all logic partitions)) must be < sizeof(extended partition), will be checked at below
    size[$part]=`echo "$zeile" | $cut -d":" -f3`
    if [ "${btype[$part]}" = "e" ]; then size_ext=${size[$part]}; p_extend=1; fi

    ptype[$part]=`echo "$zeile" | $cut -d":" -f4`
    fs[$part]=`echo "$zeile" | $cut -d":" -f5`
    mount[$part]=`echo "$zeile" | $cut -d":" -f6`
    allopts=`echo "$zeile" | $cut -d":" -f7`
    boptions[${part}0]=$((`echo $allopts | $grep -o "," | wc -l`+1))
    for (( i=1; i <= "${boptions[${part}0]}"; i++ )); do
      boptions[$part$i]=`echo ${allopts} | $cut -f$i -d","`
    done
    mkfsopt[$part]=`echo "$zeile" | $cut -d":" -f8`
    parts=$(($parts+1))
    oldzeile=$zeile
    zeile=`$head -n$(($zeilenr+$parts)) $UAPRE | $tail -n1`
  done
  output d "done"
  output d -n ">>Verifying..."
  if [ "$p_extend" != "" ]; then
    log_size=0
    for ((i=1; i < parts; i++ )); do
      if test "${btype[$i]}" = "l" -a "${size[$i]}" != "*";then log_size=$(($log_size+${size[$i]})); fi
    done
    if [ "$log_size" -gt "$size_ext" ]; then
      die "Sum of all l-part sizes is greater than the e-part size, exiting"
    fi
  fi
  output d "done"
  p_extend=""

  output d -n ">>Creating fdisk input..."
  echo o > $CMDFILE
  for ((i=1;i<parts;i++)); do
    if [ "${btype[$i]}" = "x" ]; then
	continue
    fi
    echo n >> $CMDFILE
    # the realy funny part :)
    # we can only have one e-partition and we need one e to have l
    
    if [ "${btype[$i]}" = "p" ]; then
	echo ${btype[$i]} >> $CMDFILE
    elif [ "${btype[$i]}" = "e" -a "$p_extend" = "" ]; then
	p_extend=1
	echo ${btype[$i]} >> $CMDFILE
    elif [ "${btype[$i]}" = "l" -a "$p_extend" != "" ]; then
	echo ${btype[$i]} >> $CMDFILE
    else
	die "Error in partitioning scheme, exiting"
    fi

    echo $i >> $CMDFILE
    echo "" >> $CMDFILE
    if [[ "${size[$i]}" = "*" ]]; then
      echo "" >> $CMDFILE
    else
      echo "+${size[$i]}M" >> $CMDFILE
    fi

    for ((j=1; j <= ${boptions[${i}0]}; j++)); do
      echo ${boptions[${i}${j}]} >> $CMDFILE
    done
  done
  echo "w" >> $CMDFILE
  output d "done"
  output d -n ">>Creating partition table on $DISC (may take a while)..."
  /sbin/fdisk /dev/$DISC < $CMDFILE > /dev/null 2>&1 || die "fdisk"
  output d done

  output d -n ">>Creating filesystems"
  for ((i=1; i<parts; i++)); do
      output d -n "."
      if [ "${fs[$i]}" = "swap" ]; then
	/sbin/mkswap ${mkfsopt[$i]} /dev/${DISC}$i > /dev/null 2>&1 || die "mkswap"
      elif [ -x /sbin/mkfs.${fs[$i]} ]; then
	/sbin/mkfs.${fs[$i]} ${DMKFSOPT[${fs[$i]}]} ${mkfsopt[$i]} /dev/${DISC}$i > /dev/null 2>&1 || die "mkfs"
      else
	die "unknown fs or bin not found"
      fi
  done
  output d "done"
  
  output d -n ">>Writing mountpoint informations..."
  for ((i=1;i<parts;i++)); do
      if [ "${mount[$i]}" = "" ]; then continue; fi
      echo "-t ${fs[$i]} /dev/${DISC}$i /target${mount[$i]}" > /tmp/mount
  done
  output d "done"
done

output d -n ">Mounting..."
rootmnt=`$grep /target/ /tmp/mount`
$mount $rootmnt || die "No mount for /"
cnt=`$cat /tmp/mount | wc -l`
for ((i=1;i<$(($cnt+1));i++)); do
  zeile=`$head -n$i /tmp/mount | $tail -n1`
  # we wont mount / again 
  if [ "$zeile" = "$rootmnt" ]; then continue; fi
  
  $mkdir -p `echo $zeile | $cut -d" " -f2`
  $mount $zeile || die "$zeile could not be mounted"
done
output d "done"
