#/bin/bash -e
# TechNexion Camera Driver Modules Installation for
# Nvidia Jetson ORIN NANO Development Kits.
# Before installing, You should backup your image to avoid
# there are any files you lost.

MODULE_FILE="tevs.ko"
SERVICE_FILE="tn_cam.service"
TGT_SERVICE_FILE="/etc/systemd/system/"$SERVICE_FILE

REF_LEBEL_NAME="primary"
BOOT_DTB_DIR="/boot/dtb/"
REF_DTB_FILE="kernel_tegra234-p3768-0000+p3767-0005-nv.dtb"
EXTLINUX_CONF="/boot/extlinux/extlinux.conf"

check_default_dtb() {
    if [ -n "$1" ] && [ -f "$BOOT_DTB_DIR/$1" ]; then
        echo "File $1 exists in $BOOT_DTB_DIR"
    else
        echo "File $1 does not exist in $BOOT_DTB_DIR"

        # Find the first file in the directory
        EXISTING_FILE=$(ls -1 "$BOOT_DTB_DIR" | head -n 1)

        if [ -n "$EXISTING_FILE" ]; then
            REF_DTB_FILE="$EXISTING_FILE"
            echo "Setting REF_DTB_FILE to existing file: $REF_DTB_FILE"
        else
            echo "No files found in $BOOT_DTB_DIR"
        fi
    fi
}

add_tncam_conf() {
    echo "Add TN-CAM Configuration for modules: $1"
    # sudo sed -i "s/DEFAULT .*/DEFAULT tn-$1/" $EXTLINUX_CONF
    CHECKED_CONF=$(cat $EXTLINUX_CONF| grep -n "^\s*LABEL tn-$1\s*$")
    if [ -n "$CHECKED_CONF" ]; then
        return 27
    fi
    TEVS_CONF=$(awk "/LABEL $REF_LEBEL_NAME/,/APPEND /" $EXTLINUX_CONF | \
    sed -e "s|LINUX /boot/Image|&\n      FDT /boot/dtb/$REF_DTB_FILE\n      OVERLAYS /boot/$DTB_FILE|" | \
    sed "s/LABEL primary/LABEL tn-$1/")
    sudo bash -c "echo -e '\n\n$TEVS_CONF' >> $EXTLINUX_CONF"
}

set_default_conf() {
    echo "Set Default Configuration for modules: $1"
    sudo sed -i "s/DEFAULT .*/DEFAULT tn-$1/" $EXTLINUX_CONF
}

install_tncam_dtbo() {
    echo "Install TN-CAM DTBO file: $1"
    TGT_DTB_FILE="/boot/"$1
    sudo cp dtbs/$1 $TGT_DTB_FILE
    echo "Installed TN-CAM DTB file Done."
}

get_kernel_version() {
    TEGRA_KERNEL_VER=$(uname -r)
}

get_l4t_version() {
	L4T_VER=$(dpkg-query -W -f='${Version}' nvidia-l4t-core 2>/dev/null \
			| cut -d- -f1)
}

install_tncam_modules() {
    echo "Install TN-CAM modules: $2"
    TGT_MODULE_FILE=/lib/modules/$TEGRA_KERNEL_VER/updates/drivers/media/i2c/$1
	sudo mkdir -p $TGT_MODULE_FILE
    sudo cp $1/$2 $TGT_MODULE_FILE
}

install_tncam_service() {
    echo "Install TN-CAM service..."
    SERVICE_CONTENT=$(cat $SERVICE_FILE | \
    sed "s/KERNEL_VER/$TEGRA_KERNEL_VER/g")
    sudo bash -c 'echo -e "\n\n'"$SERVICE_CONTENT"'" > '"$TGT_SERVICE_FILE"
    echo "Launch TN-CAM Service..."
    sudo systemctl daemon-reload
    sudo systemctl enable $SERVICE_FILE
    sudo systemctl start $SERVICE_FILE 2>/dev/null
}

# Start to install TechNexion Camera Driver for Jetson ORIN NANO
sudo echo "" > /dev/null # Access sudo Permissions
cat << EOF
****** TechNexion Camera Driver Installation ******
This installation is easy to install TechnNexion Camera Drivers for Nvidia
Jetson Development Kits. Before start to install camera driver,
You should BACKUP your image to avoid any file you lost while installing process.
EOF
read -p "Do you want to continue?[Y/n]" choice

if [ "$choice" = "y" ] || [ "$choice" = "Y" ]; then
	echo "Continuing with the installation..."
	get_kernel_version
	get_l4t_version
	check_default_dtb

    install_tncam_modules "technexion/tevs" "tevs.ko"
    install_tncam_modules "technexion/vls3" "vls3.ko"
    install_tncam_modules "technexion/maxim-gmsl" "max96724.ko"
    install_tncam_modules "technexion/maxim-gmsl" "max96716a.ko"
    install_tncam_modules "technexion/maxim-gmsl" "max96717.ko"

	if [ "$L4T_VER" = "36.4.3" ] || [ "$L4T_VER" = "36.4.4" ]; then
cat << EOF
Select platform:
	[1]: Jetson Orin Nano
	[2]: Jetson AGX Orin (only support JP6.2.x)
EOF
		read -p "Which platform do you select?[default:1]" platform
		platform=${platform:-"1"}
		if [ "$platform" = "1" ]; then
			install_tncam_dtbo "tegra234-p3767-camera-p3768-tevs-dual.dtbo"
			install_tncam_dtbo "tegra234-p3767-camera-p3768-vls3.dtbo"
			install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2.dtbo"
			install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-fsync.dtbo"
			install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-tunnel.dtbo"
			install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-tunnel-fsync.dtbo"
			install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-fsync-external.dtbo"
cat << EOF
Select modules:
	[1]: TEVS: TEVS Series MIPI Cameras with TEV-RPI22 Adaptor
	[2]: VLS3: VLS3 Series Cameras with VLS3-ORIN-EVK Adaptor
	[3]: VLS-GM2: VLS-GM2 Series Cameras with VL-GM2-8CAM-RPI22 Adaptor
EOF
			read -p "Which modules do you select?[default:1]" module
			module=${module:-"1"}
			if [ "$module" = "1" ] || [ "$module" = "tevs" ] || [ "$module" = "TEVS" ] ; then
				module="tevs"
				echo "Installing module: $module"
				DTB_FILE="tegra234-p3767-camera-p3768-tevs-dual.dtbo"
				add_tncam_conf $module
				set_default_conf $module
			elif [ "$module" = "2" ] || [ "$module" = "vls3" ] || [ "$module" = "VLS3" ] ; then
				module="vl316-vls"
				echo "Installing module: $module"
				DTB_FILE="tegra234-p3767-camera-p3768-vls3.dtbo"
				add_tncam_conf $module
				set_default_conf $module
			elif [ "$module" = "3" ] || [ "$module" = "vls-gm2" ] || [ "$module" = "VLS-GM2" ] ; then
				module="vls-gm2"
				echo "Installing module: $module"
				DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
				add_tncam_conf $module
				module="vls-gm2-fsync"
				echo "Installing module: $module"
				DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
				add_tncam_conf $module
				module="vls-gm2-tunnel"
				echo "Installing module: $module"
				DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
				add_tncam_conf $module
				module="vls-gm2-tunnel-fsync"
				echo "Installing module: $module"
				DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
				add_tncam_conf $module
				module="vls-gm2-fsync-external"
				echo "Installing module: $module"
				DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
				add_tncam_conf $module
				module="vls-gm2"
				set_default_conf $module
			else
				echo "Cannot Support this Module:$module"
				exit 27
			fi
		elif [ "$platform" = "2" ]; then
			install_tncam_dtbo "tegra234-p3737-camera-vls-gm2-overlay.dtbo"
			install_tncam_dtbo "tegra234-p3737-camera-vls-gm2-fsync-overlay.dtbo"
			install_tncam_dtbo "tegra234-p3737-camera-vls-gm2-tunnel-overlay.dtbo"
			install_tncam_dtbo "tegra234-p3737-camera-vls-gm2-tunnel-fsync-overlay.dtbo"
			install_tncam_dtbo "tegra234-p3737-camera-vls-gm2-fsync-external-overlay.dtbo"

			module="vls-gm2"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3737-camera-$module-overlay.dtbo"
			add_tncam_conf $module
			module="vls-gm2-fsync"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3737-camera-$module-overlay.dtbo"
			add_tncam_conf $module
			module="vls-gm2-tunnel"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3737-camera-$module-overlay.dtbo"
			add_tncam_conf $module
			module="vls-gm2-tunnel-fsync"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3737-camera-$module-overlay.dtbo"
			add_tncam_conf $module
			module="vls-gm2-fsync-external"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3737-camera-$module-overlay.dtbo"
			add_tncam_conf $module
			module="vls-gm2"
			set_default_conf $module
		else
			echo "Cannot Support this Platform:$platform"
			exit 27
		fi
	else
		install_tncam_dtbo "tegra234-p3767-camera-p3768-tevs-dual.dtbo"
		install_tncam_dtbo "tegra234-p3767-camera-p3768-vls3.dtbo"
		install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2.dtbo"
		install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-fsync.dtbo"
		install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-tunnel.dtbo"
		install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-tunnel-fsync.dtbo"
		install_tncam_dtbo "tegra234-p3767-camera-p3768-vls-gm2-fsync-external.dtbo"
cat << EOF
Select modules:
	[1]: TEVS: TEVS Series MIPI Cameras with TEV-RPI22 Adaptor
	[2]: VLS3: VLS3 Series Cameras with VLS3-ORIN-EVK Adaptor
	[3]: VLS-GM2: VLS-GM2 Series Cameras with VL-GM2-8CAM-RPI22 Adaptor
EOF
		read -p "Which modules do you select?[default:1]" module
		module=${module:-"1"}
		if [ "$module" = "1" ] || [ "$module" = "tevs" ] || [ "$module" = "TEVS" ] ; then
			module="tevs"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3767-camera-p3768-tevs-dual.dtbo"
			add_tncam_conf $module
			set_default_conf $module
		elif [ "$module" = "2" ] || [ "$module" = "vls3" ] || [ "$module" = "VLS3" ] ; then
			module="vl316-vls"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3767-camera-p3768-vls3.dtbo"
			add_tncam_conf $module
			set_default_conf $module
		elif [ "$module" = "3" ] || [ "$module" = "vls-gm2" ] || [ "$module" = "VLS-GM2" ] ; then
			module="vls-gm2"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
			add_tncam_conf $module
			module="vls-gm2-fsync"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
			add_tncam_conf $module
			module="vls-gm2-tunnel"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
			add_tncam_conf $module
			module="vls-gm2-tunnel-fsync"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
			add_tncam_conf $module
			module="vls-gm2-fsync-external"
			echo "Installing module: $module"
			DTB_FILE="tegra234-p3767-camera-p3768-$module.dtbo"
			add_tncam_conf $module
			module="vls-gm2"
			set_default_conf $module
		else
			echo "Cannot Support this Module:$module"
			exit 27
		fi
	fi

    if [ $? -eq 27 ]; then
        echo "$module have existed in $EXTCONF"
        echo "Set default configuration for $module."
    fi
    install_tncam_service

    echo "Finish Camera Driver Installation. Return Code:["$?"]"
    if [ $? -eq 0 ]; then
        echo "You should Reboot Device to enable $module Cameras."
        read -p "Do you want to reboot now?[Y/n]" choice
        if [ "$choice" = "y" ] || [ "$choice" = "Y" ]; then
            echo "Rebooting...."
            sudo reboot
        else
            echo "Reboot manually later."
        fi
    fi
else
    echo "Installation aborted."
fi