#!/bin/bash

INTERFACE=$(ip -o -4 route show to default | awk 'NR==1{print $5}')
INSECURE_MOUNT_MARKER_FILE="/etc/fw_insecure_nfs_mount"

function syntaxErr
{
	/bin/echo ""
	/bin/echo "|----------------------------|"
	/bin/echo "| Welcome to Imaging Control |"
	/bin/echo "|----------------------------|"
	/bin/echo ""
	/bin/echo ""
	/bin/echo "Examples:"
	/bin/echo ""
	/bin/echo "imaging-control networksetup static"
	/bin/echo "imaging-control networksetup dhcp"
	/bin/echo "imaging-control subnet add"
	/bin/echo "imaging-control subnet remove"
	/bin/echo "imaging-control increase harddrive"
	/bin/echo "imaging-control list windowsimages"
	/bin/echo "imaging-control disable windowsimaging"
	/bin/echo "imaging-control enable windowsimaging"
    /bin/echo "imaging-control enable secure-mount" 
}

ip_valid() {
    ipaddress="$1"
    # Check if the format looks right_
    echo "$ipaddress" | egrep -qE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' || return 1
    #check that each octect is less than or equal to 255:
    echo $ipaddress | awk -F'.' '$1 <=255 && $2 <= 255 && $3 <=255 && $4 <= 255 {print "Y" } ' | grep -q Y || return 1
    return 0
}

netmask_valid() {
    netmask="$1"
    # Check if the format looks right_
    echo "$netmask" | egrep -qE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' || return 1
    #check that each octect is less than or equal to 255:
    echo $netmask | awk -F'.' '$1 <=255 && $2 <= 255 && $3 <=255 && $4 <= 255 {print "Y" } ' | grep -q Y || return 1
    return 0
}

gateway_valid() {
    gateway="$1"
    # Check if the format looks right_
    echo "$gateway" | egrep -qE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' || return 1
    #check that each octect is less than or equal to 255:
    echo $gateway | awk -F'.' '$1 <=255 && $2 <= 255 && $3 <=255 && $4 <= 255 {print "Y" } ' | grep -q Y || return 1
    return 0
}
dns_valid() {
    dns="$1"
    # Check if the format looks right_
    echo "$dns" | egrep -qE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' || return 1
    #check that each octect is less than or equal to 255:
    echo $dns | awk -F'.' '$1 <=255 && $2 <= 255 && $3 <=255 && $4 <= 255 {print "Y" } ' | grep -q Y || return 1
    return 0
}

function static(){
read -p "Enter a valid IP: " ipaddress
while ! ip_valid "$ipaddress"
do
	read -p "Not a valid IP. Re-enter: " ipaddress
done

read -p "Enter a valid subnet mask: " netmask
while ! netmask_valid "$netmask"
do
        read -p "Not a valid subnet mask. Re-enter: " netmask
done
read -p "Enter a valid gateway: " gateway
while ! gateway_valid "$gateway"
do
        read -p "Not a valid gateway. Re-enter: " gateway
done

read -p "Enter a valid DNS IP: " dns
while ! dns_valid "$dns"
do
    read -p "Not a valid DNS IP. Re-enter: " dns
done

read -p "Do you want to create a backup of the existing network configuration file? (Note it will override old backup files if there are any) (y/n): " backup_choice

if [ "$backup_choice" = "y" ] || [ "$backup_choice" = "Y" ]; then
    if [ -f /etc/network/interfaces ]; then
        cp /etc/network/interfaces /etc/network/interfaces.bak
        echo "Backup created at /etc/network/interfaces.bak"
    else
        echo "No existing configuration file found. No backup needed."
    fi
fi

if [ $(cat /etc/NetworkManager/NetworkManager.conf | sed -n '/dns=none/p' | wc -l) != 1 ]; then
    sed -i '/^\[main.*/a dns=none' /etc/NetworkManager/NetworkManager.conf
fi

mv /etc/resolv.conf /etc/resolv.conf.backup

echo "# The loopback network interface
auto lo
iface lo inet loopback
" > /etc/network/interfaces


echo "auto $INTERFACE
iface $INTERFACE inet static
    address $ipaddress
    netmask $netmask
    gateway $gateway" >> /etc/network/interfaces

echo "nameserver $dns" >> /etc/resolv.conf

systemctl restart NetworkManager
systemctl restart networking
systemctl restart dnsmasq
}

function dhcp(){
if [ $(cat /etc/NetworkManager/NetworkManager.conf | sed -n '/dns=none/p' | wc -l) == 1 ]; then
    sed -i '/dns=none/d' /etc/NetworkManager/NetworkManager.conf
fi

read -p "Do you want to create a backup of the existing network configuration file? (Note it will override old backup files if there are any) (y/n): " backup_choice

if [ "$backup_choice" = "y" ] || [ "$backup_choice" = "Y" ]; then
    if [ -f /etc/network/interfaces ]; then
        cp /etc/network/interfaces /etc/network/interfaces.bak
        echo "Backup created at /etc/network/interfaces.bak"
    else
        echo "No existing configuration file found. No backup needed."
    fi
fi

echo "# The loopback network interface
auto lo
iface lo inet loopback
" > /etc/network/interfaces

echo "auto $INTERFACE
iface $INTERFACE inet dhcp" >> /etc/network/interfaces

systemctl restart NetworkManager
systemctl restart networking
systemctl restart dnsmasq

}

function add(){

read -p "Enter a valid IP: " ipaddress
while ! ip_valid "$ipaddress"
do
    read -p "Not a valid IP. Re-enter: " ipaddress
done

read -p "Enter a valid subnet mask: " netmask
while ! netmask_valid "$netmask"
do
    read -p "Not a valid subnet mask. Re-enter: " netmask
done


echo "dhcp-range=$ipaddress,proxy,$netmask" >> /imaging/scripts/templates/dnsmasq_custom.conf

systemctl restart NetworkManager
}

function remove(){

if [ ! -f /imaging/scripts/templates/dnsmasq_custom.conf ]; then
    return
fi

subnets=$(echo | grep 'dhcp-range' /imaging/scripts/templates/dnsmasq_custom.conf | grep -v 'start_address'| cut -d '=' -f 2 | cut -d ',' -f 1 | tr '\n' ',')

IFS=',' read -a array <<< "$subnets"

createmenu ()
{
  arrsize=$1
  echo "Select a subnet to remove:"
  select option in "${@:2}"; do
    if [ 0 -le "$REPLY" ] && [ "$REPLY" -le $((arrsize-0)) ];
    then
        echo "$option has been removed"
      
        sed --in-place /"$option"/d /imaging/scripts/templates/dnsmasq_custom.conf
        systemctl restart NetworkManager
        break;
    else
        echo "Incorrect Input: Select a number 1-$arrsize"
    fi
  done
}

createmenu "${#array[@]}" "${array[@]}"
}

function harddrive ()
{

#root check 
if [ $EUID -gt 0 ] ; then echo "run $0 as root , please" ; exit ; fi

#check for available partitions
if [ $(fdisk -l /dev/sda3 | wc -l) -gt 0 ] ; then
	if [ $(fdisk -l /dev/sda4 | wc -l) -gt 0 ] ; then
		echo "you already have 4 primary partitions, you'll have to create a new vm"
		exit 1
	else
		partname="/dev/sda4"
	fi
else
	partname="/dev/sda3"
fi
# Get the volume group name
vg_name=$(vgs --noheadings -o vg_name | sed 's/ //g')

# The naming convention used in LVM (Logical Volume Management) under different Linux distributions.
# In CentOS, the LVM names typically use a single dash (-), whereas in Debian-based systems, a double dash (--)
# is used to represent a single dash in volume group (VG) and logical volume (LV) names
# Therefore, when a VG or LV name itself contains a dash, it must be escaped. In our case the volume group is `filewave-vg`
vg_dev_mapper=$(vgs --noheadings -o vg_name | sed 's/ //g' | sed 's/-/--/g')

# Check if there is more than one volume group name
if [[ $(echo "$vg_name" | wc -l) -gt 1 ]]; then
    echo "Error: There is more than one volume group name."
    exit 1
fi
partnumber=$(echo $partname|sed -e 's#/dev/sda##')
echo "Located $partname as a candidate for an additional partition... creating"

#try to create the partition, and see what the results are
checkfreesectors=$((echo n; echo p; echo $partnumber; echo; echo; echo q) | fdisk /dev/sda | grep "No free sectors available" | wc -l)
if [ $checkfreesectors -gt 0 ] ; then 
	echo "################################################################"
	echo " There is no further space available on your device."
	echo " increase the disk space through VmWare/Virtualbox and try again "
	echo "################################################################"
	exit
fi

#actually create the partition and set its type
(echo n; echo p; echo $partnumber; echo; echo; echo t;echo $partnumber;echo 8E;echo w) | fdisk /dev/sda

#create the script for extending the logical volume after reboot
cat >/root/extendlvm.sh<<EOT
#!/bin/bash
set -e
echo "##############################################"
echo "Extending Partition size now ..." 
echo "##############################################"
if ! pvs $partname &> /dev/null; then
    pvcreate $partname
    vgextend $vg_name $partname
    lvextend -l +100%FREE /dev/mapper/$vg_dev_mapper-root
    resize2fs /dev/mapper/$vg_dev_mapper-root
    echo "##############################################"
    echo "Resizing complete. Enjoy your new free space !"
    echo "##############################################"
else
    echo "Physical volume $partname already initialized. Skipping."
fi
df -h .
sed -i '/\/root\/extendlvm.sh/d' /root/.bash_profile
rm /root/extendlvm.sh
EOT
chmod +x /root/extendlvm.sh

#add the script to bash_profile if not already present
if ! grep -q "/root/extendlvm.sh" /root/.bash_profile; then
    echo "/root/extendlvm.sh" >> /root/.bash_profile
fi

#tell the user that a reboot must be done, and he has to log in again afterwards to make it work
echo "#############################################################"
echo "Partition created successfully. The system has to reboot now"
echo "To complete resizing, log in as root after the reboot"
echo 
echo "                Press ENTER to Reboot"
echo "#############################################################"
if [ "$1" != "--noinput" ]; then
    read byebye
    echo "rebooting now ... remember to log in again please"
    reboot
fi
}

function windowsimages()
{
if ls /imaging/images/windows/FS*/image.json 1> /dev/null 2>&1;
then
winimages=$(grep -Po '"name":.*?[^\\]",' /imaging/images/windows/FS*/image.json | awk -F : '{ print $3 }' | tr -d '"' | tr -d ',')
echo "$winimages"
else
echo "No Windows images found"
fi
}

function disablewin()
{
sed -i '/disable-windows/d' /imaging/scripts/templates/dnsmasq_custom.conf
echo "disable-windows" >> /imaging/scripts/templates/dnsmasq_custom.conf

systemctl restart NetworkManager
echo "Windows Imaging has been disabled"
}

function enablewin()
{
sed -i '/disable-windows/d' /imaging/scripts/templates/dnsmasq_custom.conf

systemctl restart NetworkManager
echo "Windows Imaging has been enabled"
}

function enable_beta_repository()
{
    # IMPORTANT FWRD-14418 we disabled debian repo in favor of the upgrade script
    # but let's keep this code for now...
    
    renew_gpg_key

    ARCH=$(dpkg --print-architecture)
    echo "deb [arch=$ARCH signed-by=/etc/apt/keyrings/filewave.gpg] https://fwbetas.filewave.com/debian/apt-repo beta main" | tee /etc/apt/sources.list.d/filewave-beta.list > /dev/null
    apt-get update

    echo "beta repository has been successfully added; Now you can run apt-get upgrade"
}

function disable_beta_repository()
{
    # Remove the beta repository list file
    rm -f /etc/apt/sources.list.d/filewave-beta.list

    # Update the package lists
    apt-get update

    echo "beta repository has been successfully removed;"
}

function renew_gpg_key()
{
    # IMPORTANT FWRD-14418 we disabled debian repo in favor of the upgrade script
    # but let's keep this code for now...

    # Pull the tooling for apt-key authorization
    apt-get update
    install -m 0755 -d /etc/apt/keyrings
    # We pull the public key from AWS S3 in order to authorize ourselfs
    # All the packages located in listed debian repositories are signed with that key
    curl -fsSLk https://fwpgp.s3.amazonaws.com/filewave.pgp | gpg --dearmor -o /etc/apt/keyrings/filewave.gpg --yes
    chmod a+r /etc/apt/keyrings/filewave.gpg

    echo "Successfully renewed GPG key"
}

enable_secure_mount() {
    echo "Secure NFS mount requires encryption and uses NFSv4 which improves security but has a significant impact on imaging speed."
    if [ ! -f "$INSECURE_MOUNT_MARKER_FILE" ]; then
        echo "Secure mount is already enabled."
    else
        echo "Enabling secure mount..."
        rm -f "$INSECURE_MOUNT_MARKER_FILE"
        ufw delete allow 2049/tcp
        ufw delete allow 2049/udp
        ufw reload
        echo "Secure NFS mounting will be enabled after reboot."
    fi
}

disable_secure_mount() {
    if [ -f "$INSECURE_MOUNT_MARKER_FILE" ]; then
        echo "Secure mount is already disabled (insecure mode)."
    else
        echo "Disabling secure mount (allowing insecure)..."
        touch "$INSECURE_MOUNT_MARKER_FILE"
        ufw allow 2049/tcp
        ufw allow 2049/udp
        ufw reload
        echo "Insecure NFS mounting will be enabled after reboot."
    fi
}


if [ "$1" == "networksetup" ]; then
  case "$2"
  in
    "static")
    static
    ;;
    "dhcp")
    dhcp
    ;;
    *)
    syntaxErr
    ;;
   esac
elif [ "$1" == "subnet" ]; then
   case "$2"
   in
	"add")
	add 
	;;
	"remove")
	remove
	;;
    *)
    syntaxErr
    ;;
	esac
elif [ "$1" == "increase" ]; then
   case "$2"
   in
	"harddrive")
	if [ "$4" != "--noinput" ]; then
	    echo "Note: You can only extend the hard drive once. Make sure to choose an appropriate size."
      echo
	    read -r -p "Have you extended the hard drive in the VM settings, and do you want to proceed? [y/N] " response
	else
	    response="Y"
	fi
    if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
        harddrive $4
     else
            echo "Please shutdown the VM and increase the hard drive size in the VM settings menu."
            exit
    fi
    ;;
    *)
    syntaxErr
    ;;
	esac
elif [ "$1" == "list" ]; then
   case "$2"
   in
	"windowsimages")
	windowsimages
	;;
    *)
    syntaxErr
    ;;
	esac
elif [ "$1" == "disable" ]; then
   case "$2" 
   in
	"windowsimaging")
	disablewin
	;;
    "secure-mount")
    disable_secure_mount
    ;;
    *)
    syntaxErr
    ;;
	esac
elif [ "$1" == "enable" ]; then
   case "$2"
   in
	"windowsimaging")
	enablewin
	;;
    "secure-mount")
    enable_secure_mount
    ;;
    *)
    syntaxErr
    ;;
    esac
else
	syntaxErr
fi
