#!/bin/bash
set -x

#---------------------------------------------
# This script takes:
#
# Argument #1 - the device partition path (e.g. "/dev/sdc1").
# Argument #2 - fstype, either "vfat", "exfat", "ext4" or "filr".
# Argument #3 - the device's volume label (e.g. "FastecSD").
# Argument #4 - [optional] "1" = sanitize the drive (only applicable for SSDs).
#
# It umounts, repartitions the entire raw device, and creates a  
# single partition using fdisk, and formats as FAT32 or EXT4.
#---------------------------------------------

#---------------------------------------------
function err_exit
{
    /usr/bin/logger -s "Had a problem with the formatter!"
    exit $ERR_STATUS
}
#---------------------------------------------

#---------------------------------------------
function do_sanitize
{
    # This is actually a secure erase operation. Our NVME SSD
    # does not support "secure-erase".
    nvme format $RAWDISK --ses=1
    if [ $? != 0 ]; then
        ERR_STATUS=10
        err_exit
    fi
}
#---------------------------------------------

#---------------------------------------------
function do_mount
{
    if [ -e $PARTITION ]; then
		if [ "$RAWDISK" = "/dev/nvme0n1" ] || [ "$RAWDISK" = "/dev/nvme1n1" ]; then
            /usr/bin/udevadm trigger -t devices -c add --name-match $PARTITION
		else
            sudo --user=$SUDO_USER udisksctl mount -b $PARTITION
		fi
    fi
}
#---------------------------------------------

#---------------------------------------------
function do_unmount
{
    # If we have a partition, make sure we unmount it.
    if [ -e $PARTITION ]; then
		# Make sure it's actually mounted.
		findmnt -rno SOURCE "$PARTITION" > /dev/null
		if [ $? -eq 0 ]; then
			if [ "$RAWDISK" = "/dev/nvme0n1" ] || [ "$RAWDISK" = "/dev/nvme1n1" ]; then
				/usr/bin/udevadm trigger -t devices -c remove --name-match $PARTITION
				sleep 1
				umount -f $PARTITION
			else
				udisksctl unmount -b $PARTITION
			fi
		fi
    fi
}
#---------------------------------------------


# Sanity check the command line.
if [ $# -lt 3 ]; then
    echo "usage: $0 device_partition fstype label [sanitize]"
    exit 1
fi

# Make sure we have a user value.
if [ "$SUDO_USER" == "" ]; then
    SUDO_USER=fascam
fi

PARTITION=$1
LABEL=$3

# Convert the FSTYPE argument from a string to the value
# used by the fdisk program.
case "$2" in

vfat)  FSTYPE="msdos"
    ;;
exfat) FSTYPE="exfat"
    ;;
ntfs)  FSTYPE="ntfs"
    ;;
ext?)  FSTYPE="gpt"
    ;;
filr)  FSTYPE="filr"
    ;;
*)  echo  "Unrecognized filesystem type"
    exit 2
    ;;
esac

case "$PARTITION" in

/dev/sd??)  RAWDISK="${1%?}"
    ;;
/dev/nvme0n1p?)  RAWDISK=/dev/nvme0n1
    ;;
/dev/nvme1n1p?)  RAWDISK=/dev/nvme1n1
    ;;
/dev/mmcblk0p1)  RAWDISK=/dev/mmcblk0
    ;;
*)  echo  "Unrecognized device"
    exit 3
    ;;
esac

if [ ! -e $RAWDISK ]; then
    logger -s "$RAWDISK doesn't exist!"
    exit 4
fi

# echo RAWDISK=$RAWDISK, PARTITION=$PARTITION >> /tmp/debug

# Setup parameters based on which disk we're mucking with.
if [ "$RAWDISK" = "/dev/nvme0n1" ] || [ "$RAWDISK" = "/dev/nvme1n1" ]; then
    if [ "$LABEL" = "" ]; then
		LABEL=`~fascam/.config/Fastec/scripts/get_oem_name SSDLabel`
		if [ "$LABEL" = "" ]; then
			LABEL="FastecSSD" 
		fi
    fi

    # Check for a sanitize option here.
    if [ $# == 4 ]; then
		SANITIZE=$4
    fi
elif [ "$RAWDISK" = "/dev/mmcblk0" ]; then
    if [ "$LABEL" = "" ]; then
		LABEL=`~fascam/.config/Fastec/scripts/get_oem_name SDCardLabel`
		if [ "$LABEL" = "" ]; then
			LABEL="FastecSD"
		fi
    fi
else
    if [ "$LABEL" = "" ]; then
		LABEL=`~fascam/.config/Fastec/scripts/get_oem_name USBLabel`
		if [ "$LABEL" = "" ]; then
			LABEL="FastecMedia"
		fi
    fi
fi

# Make sure all data is written out to the drive(s).
sync
sync
sync

# If we have a partition, make sure we unmount it.
do_unmount

# Check to see if we're sanitizing.
if [ "$SANITIZE" = "1" ]; then
    # Sanitize the SSD.
    do_sanitize
else
    # Blow away any existing MBR.
    /usr/bin/wipefs -a $RAWDISK
    if [ "$RAWDISK" = "/dev/nvme0n1" ] || [ "$RAWDISK" = "/dev/nvme1n1" ]; then
	   dd if=/dev/zero of=$RAWDISK bs=4096 count=1M
	   sync
    fi
fi

# If we're supposed to create the Fastec Imaging LR File system
# then we're done.
if [ $FSTYPE = "filr" ]; then
    echo "All done"
    exit 0
elif [ $FSTYPE = "exfat" -o $FSTYPE = "ntfs" ]; then
    # Reformat the drive, but give it a label type of MSDOS.
    /usr/bin/parted -s $RAWDISK mklabel msdos
else
    # Reformat the drive.
    /usr/bin/parted -s $RAWDISK mklabel $FSTYPE
fi

# Make the file system on the drive...
if  [ $FSTYPE = "msdos" ]; then
    # Create the partition.
    /usr/bin/parted -s -a optimal $RAWDISK mkpart p fat32 0% 100%

    # Delay
    sleep 1

    # This sometimes triggers UDEV to mount the partition. Make
    # sure we unmount it.
    do_unmount

    # Delay
    sleep 1

    # Format the drive.
    /usr/bin/mkfs.vfat -v -n "$LABEL" $PARTITION
    if [ $? != 0 ]; then
		ERR_STATUS=5
		err_exit
    fi
elif [ $FSTYPE = "gpt" ]; then
    # Create the partition.
    /usr/bin/parted -s -a optimal $RAWDISK mkpart p ext4 0% 100%

    # Delay
    sleep 1

    # This sometimes triggers UDEV to mount the partition. Make
    # sure we unmount it.
    do_unmount

    # Delay
    sleep 1

    # Format the drive.
    /usr/bin/mkfs.ext4 -T largefile -L "$LABEL" -F $PARTITION
    if [ $? != 0 ]; then
		ERR_STATUS=5
		err_exit
	fi
    /usr/bin/tune2fs -m 1 -c 10 -i 1w -o journal_data_writeback $PARTITION
elif [ $FSTYPE = "exfat" ]; then
    # Create the partition.
    /usr/bin/parted -s -a optimal $RAWDISK mkpart p ntfs 0% 100%

    # Delay
    sleep 1

    # This sometimes triggers UDEV to mount the partition. Make
    # sure we unmount it.
    do_unmount

    # Delay
    sleep 1

    # Format the drive.
    /usr/bin/mkfs.exfat -n "$LABEL" $PARTITION
    if [ $? != 0 ]; then
		ERR_STATUS=5
		err_exit
    fi
elif [ $FSTYPE = "ntfs" ]; then
    # Create the partition.
    /usr/bin/parted -s -a optimal $RAWDISK mkpart p ntfs 0% 100%

    # Delay
    sleep 1

    # This sometimes triggers UDEV to mount the partition. Make
    # sure we unmount it.
    do_unmount

    # Delay
    sleep 1

    # Format the drive. Use "Quick" mode, which does not initialize
    # the drive with zeros and does not do bad block checking.
    /usr/bin/mkfs.ntfs -Q -L "$LABEL" $PARTITION
    if [ $? != 0 ]; then
		ERR_STATUS=5
		err_exit
    fi
else
    # Unexpected...
    ERR_STATUS=6
    err_exit
fi

# Pause for just a bit to let the format settle.
sync
sleep 1

# Mount the device.
if [ -e $PARTITION ]; then
    if [ "$RAWDISK" = "/dev/nvme0n1" ] || [ "$RAWDISK" = "/dev/nvme1n1" ]; then
	   /usr/bin/udevadm trigger -t devices -c add --name-match $PARTITION
    else
	   sudo --user=$SUDO_USER udisksctl mount -b $PARTITION
    fi

    # Make sure the mount worked OK.
    if [ $? != 0 ]; then
		ERR_STATUS=7
		err_exit
    fi

    # Pause for just a bit to let the mount happen, etc.
    sleep 2

fi

# Now, pull the label back off the device and use that
# to build the mount-point.
# DEV_LABEL=$(blkid -o export "$PARTITION" | grep "^LABEL=" | sed 's/^LABEL=//')
# MOUNTPOINT=$(df --output=target "$PARTITION" | grep "$DEV_LABEL")
MOUNTPOINT=$(udisksctl info -b "$PARTITION" | grep MountPoints | cut -d':' -f 2 | sed 's/^ *//')

# Is the drive mounted?
if [ "$MOUNTPOINT" == "" ]; then

    # Try a different mounting options if we're an NVME drive.
    if [ -e $PARTITION ]; then
	   if [ "$RAWDISK" = "/dev/nvme0n1" ] || [ "$RAWDISK" = "/dev/nvme1n1" ]; then
           sudo --user=$SUDO_USER udisksctl mount -b $PARTITION
	   fi
    fi

    # Make sure the mount worked OK.
    if [ $? != 0 ]; then
	   ERR_STATUS=7
	   err_exit
    fi

    # Pause for just a bit to let the mount happen, etc.
    sleep 2

    # Now, pull the label back off the device and use that
    # to build the mount-point.
    # DEV_LABEL=$(blkid -o export "$PARTITION" | grep "^LABEL=" | sed 's/^LABEL=//')
    # MOUNTPOINT=$(df --output=target "$PARTITION" | grep "$DEV_LABEL")
    MOUNTPOINT=$(udisksctl info -b "$PARTITION" | grep MountPoints | cut -d':' -f 2 | sed 's/^ *//')

    if [ "$MOUNTPOINT" == "" ]; then
	   ERR_STATUS=11
	   err_exit
    fi
fi

# Now set up the basic folders and files.
mkdir -p "$MOUNTPOINT/hs_video"
if [ $? != 0 ]; then
    ERR_STATUS=8
    err_exit
fi
mkdir -p "$MOUNTPOINT/DCIM/100fastc"
if [ $? != 0 ]; then
    ERR_STATUS=9
    err_exit
fi

# Add an icon for the new partition
echo -e "[autorun]\r\n" > "$MOUNTPOINT/autorun.inf"
if [ -e /opt/fastec/settings/oem/oem_media.ico ]; then
    cp /opt/fastec/settings/oem/oem_media.ico "$MOUNTPOINT/media.ico"
    echo -e "icon=media.ico\r\n" >> "$MOUNTPOINT/autorun.inf"
fi

# If possible, let's change the ownership on the drive. This won't work
# if the format doesn't support ownership (i.e., FAT-ish formats).
chown -R $SUDO_USER:disk $MOUNTPOINT

# Make sure everything is flushed to the disk.
sync
sync
sync

exit 0
