#! /bin/sh -
#
# The installer of Dragora GNU/Linux-Libre
#
# Copyright (c) 2019 Matias Fonzo, <selk@dragora.org>.
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

# Exit immediately on any error
set -e

PROGRAM="${0##*/}"
TMPDIR="${TMPDIR:-$HOME}"
TMPFILE="${TMPDIR}/${PROGRAM}.${RANDOM-0}$$"
LOCKFILE=/tmp/dragora-installer.lockfile

# Override locale settings
LC_ALL=C
LANGUAGE=C
export LC_ALL LANGUAGE

chkstatus_or_exit()
{
    status=$?

    # Clean up temporary files
    rm -f -- "$TMPFILE" "$LOCKFILE"

    # Clean up temporary subdirectory related to the installer
    if test -z "$PRESERVE"
    then
        rm -rf -- "$SUBTMPDIR"
    fi

    if test $status -ne 0
    then
        printf "%s\n" "" "^ Return status = $status" 1>&2
        exit 2;
    fi

    unset status
}

# Sanity checks

if test ! -d "$TMPDIR"
then
    echo "${PROGRAM}: \`${TMPDIR}' is not a qualified temporary directory" 1>&2
    exit 1;
fi
if test ! -w "$TMPDIR"
then
    echo "${PROGRAM}: \`${TMPDIR}' is not a writable temporary directory" 1>&2
    exit 1;
fi

trap 'chkstatus_or_exit' EXIT HUP INT QUIT ABRT TERM

umask 077;	# Remove access for all but user.

# Set a lock to allow only one instance of the installer

if ( set -C ; echo ": $PROGRAM - locked" > $LOCKFILE ) 2> /dev/null
then
    true
else
    if test -e "$LOCKFILE"
    then
        echo "Only one instance of \`${PROGRAM}' is allowed." 1>&2
        exit 1;
    else
        echo "${PROGRAM}: \`${LOCKFILE}' lock failed." 1>&2
        exit 2;
    fi
fi

# Create subdirectory to store the files produced by the installer

SUBTMPDIR="${TMPDIR}/.${PROGRAM}"	# Default sets to "${HOME}/.dragora-installer".
mkdir -p -m 700 -- $SUBTMPDIR

umask 022;	# Remove write permission for group and other.

# Detect and prepare initial list of Linux partition(s)

if fdisk -l | grep -m 1 Linux | grep -q -v swap
then
    fdisk -l | grep Linux | grep -v swap | LC_COLLATE=C sort \
     > ${SUBTMPDIR}/partitions
else
    printf "%s\n" \
     "    Linux partitions were not detected."                               \
     ""                                                                      \
     "A Linux partition is required to continue the installation.  You can"  \
     "use utilities such as fdisk(8), cfdisk(8) or parted(8) to create at"   \
     "least one Linux partition.  Then run \`${PROGRAM}' again."
     exit 1;
fi

# Determine the maximum size of the terminal to be used on the dialogues.
# Try using shell variables that set LINES and COLUMNS, first.
echo "Checking terminal size ..."
if test -z "$LINES"
then
    LINES="$(tput lines)" || \
     { LINES="$(stty size)" && LINES="${LINES% *}"; }
fi
if test -z "$COLUMNS"
then
    COLUMNS="$(tput cols)" || \
     { COLUMNS="$(stty size)" && COLUMNS="${COLUMNS#* }"; }
fi
echo "$LINES $COLUMNS"

export SUBTMPDIR LINES COLUMNS

dialog --colors \
 --backtitle "\ZbDragora 3.0 Installer" \
 --title "INSTALLER INFORMATION" \
 --cr-wrap --msgbox \
"Welcome to \Z3${PROGRAM}\Zn.\n\n\
This program prepares Dragora 3.0 to run on your computer.\n\n\
    - To set up Dragora now, press \ZuENTER\Zn.\n\n\
    - To quit, press \ZuEsc\Zn.\n\n\

Use the arrow keys to move between options and selections, also \ZuTAB\Zn to
jump from one option to another.  \ZuENTER\Zn to continue, \ZuEsc\Zn to cancel
or return to a previous menu, and \ZuCtrl+C\Zn to abort the installation at
any time.

* Here is a representation of the most commonly used keys in a QWERTY layout:

\Z3[Esc]\Zn  \Z3[F1]\Zn
                                           \Z3[<- ]\Zn  \Z3[Ins][Home][PageUp]\Zn
\Z3[TAB]\Zn                                             \Z3[Del][End ][PageDown]\Zn
                                       \Z3[-ENTER-]\Zn
           \Z3[c]\Zn                                         \Z3[^]\Zn
\Z3[Ctrl]\Zn    \Z3[          SPACE          ]\Zn               \Z3[<][V][>]\Zn
\Zn" $((LINES - 8)) $((COLUMNS - 8))

# Try to detect and mount the hybrid ISO image, there may be a USB memory
# stick already inserted.  If not, the media menu will be displayed.

mkdir -p -- /media/dragora-medium

if ! blkid -t LABEL="Dragora Packages" > /dev/null
then
    dialog --colors \
     --backtitle "\ZbInstallation Medium" \
     --title "Pendrive/SDCard/CDROM" \
     --msgbox \
"Please insert the media labeled as \"Dragora Packages\" and\n\
press \Zb\Z7ENTER\Zn to continue.  Otherwise a media selection menu\n\
will be displayed." 7 63
    if blkid -t LABEL="Dragora Packages" > /dev/null
    then
        if ! mountpoint -q /media/dragora-medium
        then
            mount -v -t iso9660 LABEL="Dragora Packages" /media/dragora-medium && \
             echo "/media/dragora-medium/packages" > ${SUBTMPDIR}/MediumFound
            sleep 2
        fi
    else
        . @PARTS@MenuMedia
    fi
else
    if ! mountpoint -q /media/dragora-medium
    then
        mount -v -t iso9660 LABEL="Dragora Packages" /media/dragora-medium
        sleep 2
    fi
    echo "/media/dragora-medium/packages" > ${SUBTMPDIR}/MediumFound
fi

# Attempt to unmount possible pre-mounted filesystem(s)
mountpoint -q /media/dragora-root/sys && umount /media/dragora-root/sys
mountpoint -q /media/dragora-root/proc && umount /media/dragora-root/proc
mountpoint -q /media/dragora-root/dev && umount /media/dragora-root/dev

# Clean up possible empty mount-directories
rmdir -- \
 /media/dragora-medium \
 /media/dragora-root 2> /dev/null || true

# Double-check to see the installation directory
if test ! -f "${SUBTMPDIR}/MediumFound"
then
    dialog --colors \
     --backtitle "\ZbInstallation Medium" \
     --title "MEDIUM NOT FOUND" \
     --sleep 7 --infobox \
"\nNo means of installation was found to proceed with\n\
the installation of Dragora.  Please check your\n\
drives and the directory containing the software\n\
packages." 8 55
    exit 99;
fi

. @PARTS@MakeSwap;		# Verify/give format to a Swap partition.
. @PARTS@MakeFS;		# Verify/give format to Linux partitions.
. @PARTS@FstabEdit;		# File system table edition (fstab).
. @PARTS@MountRoot;		# Mount root partition for installation.
. @PARTS@FstabMounts;		# Mount rest of file systems from fstab.
. @PARTS@ShowSeries;		# Show software series.
. @PARTS@InstallPackages;	# Package installation.
. @PARTS@SetPassword;		# Set password for root.
. @PARTS@MenuBootloader;	# Boot loader installation.
. @PARTS@ConfServices;		# Running services.
. @PARTS@CopyConfig;		# Copy local config files (keymap, mouse).

umount /media/dragora-root/dev   > /dev/null 2>&1 || true
umount /media/dragora-root/proc  > /dev/null 2>&1 || true

if test -e /media/dragora-root/etc/fstab
then
    if mountpoint -q /media/dragora-medium
    then
        umount /media/dragora-medium
    fi
    if test -s ${SUBTMPDIR}/SeTCDdev
    then
        _status=0
        dialog --clear --colors \
         --title "The Setup for Dragora has been completed" \
         --msgbox \
"\nWhen you are ready, you can press \Zb\Z7ENTER\Zn to eject the installation disc...\n" 8 70 || _status=$?
        if test $_status -eq 0
        then
            cdrom_device="$(cat -- ${SUBTMPDIR}/CDDevice)"

            # Try to eject using SCSI commands, fallback on CDROM eject command
            eject --scsi $cdrom_device || eject --cdrom $cdrom_device

            dialog \
             --title "The Setup for Dragora has been completed" \
             --msgbox "\nPlease remove the installation disc.\n" 7 44 || true

            # Attempt to use the tray close command
            eject -t $cdrom_device > /dev/null 2>&1 || true
        fi
        unset _status cdrom_device
    fi
fi

sync

_status=0
dialog --clear --colors \
 --backtitle "\ZbSystem restart" \
 --title "The Setup for Dragora has been completed" \
 --yesno \
"\nWould you like to reboot the system now?.\n" 7 46 || _status=$?
case $_status in
0)
    unset _status
    dialog --clear
    exec reboot -d -f
    ;;
*)
    unset _status
    echo ""
    echo ""
    echo ""
    echo "Going out to the shell..."
    echo ""
    echo ""
    exit 0
    ;;
esac

