#! /bin/bash

EFI_SIZE=860 #MiB
ETIQUETA_PARTICION1="EFI"
ETIQUETA_PARTICION2="INSTAL-WIN"
CARPETA_TRABAJO=/var/tmp/deepin-win-boot-maker

USB_DRIVES=()
USB_DRIVE_SELEC=""
USB_EFI_MONTAJE=""
USB_INSTAL_MONTAJE=""
ISO_FILE=""
ISO_LOOP=""
ISO_MONTAJE=""


proc-salir () {
	echo "Presione Enter para terminar"
	read OPCION
	exit 0
}

proc-cancelado () {

	echo "Procedimiento cancelado"
	proc-salir
}


bienvenida () {

	clear

	cat /opt/apps/deepines-win-boot-maker/intro.txt

	echo -e "\n¿Quiere ver más información y detalles? (s/N)\n"

	read OPCION

	case "$OPCION" in
		S|s )
			clear
			cat /opt/apps/deepines-win-boot-maker/info.txt
			echo "Presione Enter para continuar"
			read OPCION
			;;
	esac

	clear
}


selec-iso-file () {

	echo -e "\n----------------------------"
	echo -e "ISO del instalador de Windows\n"
	echo "1) Arrastre el archivo .iso a esta terminal"
	echo "2) Haga clic en esta terminal"
	echo -e "3) Presione Enter\n"

	read ISO_FILE

	ISO_FILE="$( echo "$ISO_FILE" | sed -e "s|^'||; s|'$||;" )"

	if [[ -f $ISO_FILE ]]; then
		
		ES_ISO="$(file $ISO_FILE | grep "ISO 9660 CD-ROM filesystem data" )"

		if [[ ! $ES_ISO ]]; then

			echo -e "\n----------------------------"
			echo "«$(basename "${ISO_FILE}")» no es un archivo ISO válido"
			proc-salir
		fi
	else
		echo "El archivo «$ISO_FILE» no existe"
		proc-salir
	fi

	clear
}

get-usb-drives () {
	LISTA="$(ls -l /dev/disk/by-path/ | grep usb | cut -d "/" -f3 | sed "s|[0-9]||g" | uniq | sort )"

	INDICE=1
	for i in $LISTA; do
		
		USB_DRIVES[$INDICE]="/dev/${i}"
		let INDICE++
	done
}

print-usb-drives () {

	INDICE=1
	for i in ${USB_DRIVES[@]}; do
		echo ${USB_DRIVES[$INDICE]}
		let INDICE++
	done
}

print-usb-drives-info () {

	if [[ ${USB_DRIVES[@]} ]]; then
		
		echo -e "\n----------------------------"
		echo -e "Unidades de almacenamiento USB\n"
		lsblk -o NAME,LABEL,SIZE,FSTYPE,PATH ${USB_DRIVES[@]}
	else
		echo -e "\n----------------------------"
		echo -e "No hay unidades de almacenamiento USB disponibles\n"
	fi
}

selec-usb-drive () {

	if [[ ${USB_DRIVES[@]} ]]; then
		
		SEGUIR=true	
		while [[ $SEGUIR == true ]]; do
			
			OPCION=""

			clear

			print-usb-drives-info

			echo -e "\n----------------------------"
			echo "Seleccione una de las unidades USB"

			CONT=1
			for i in $(print-usb-drives); do
				echo "$CONT) ${i}"
				let CONT++
			done
			echo -e "C) Cancelar\n"

			read OPCION

			case "$OPCION" in
				C|c )
					proc-cancelado
					;;
				* )
					if [[ $OPCION -ge 1 ]] && [[ $OPCION -le ${#USB_DRIVES[@]} ]]; then

						USB_DRIVE_SELEC="${USB_DRIVES[$OPCION]}"

						ISO_SIZE="$( du -b ${ISO_FILE} | cut -f1 )"
						EFI_SIZE_BYTE=$( expr ${EFI_SIZE} \* 1048576 \+ 10240 )
						USB_SIZE_REQUER=$( expr $ISO_SIZE + ${EFI_SIZE_BYTE} )
						USB_SIZE=$( lsblk -o size -b "${USB_DRIVE_SELEC}" | sed -n "2 p" )

						#Comprobar que la unidad es suficientemente grande
						if [[ $USB_SIZE -gt $USB_SIZE_REQUER ]]; then

							echo "$USB_DRIVE_SELEC seleccionado"
							SEGUIR=false
						else

							echo -e "\n----------------------------"
							echo "La unidad seleccionada es de $( echo "scale=1; ${USB_SIZE} / 1073741824" | bc ) GiB y se necesitan al menos $( echo "scale=1; ${USB_SIZE_REQUER} / 1073741824" | bc ) GiB"
							echo "Vuelva a intentarlo con una unidad de almacenamiento USB más grande"
							proc-salir
						fi

						
					else
						echo -e "\n----------------------------"
						echo "Opción inválida, presione Enter para continuar"
						read OPCION
					fi
					;;
			esac
		done
	else

		print-usb-drives-info
		echo "Conecte una unidad de almacenamiento USB y vuelva a intentarlo"
		proc-salir
	fi

		
}

format-usb-drive () {

	MODO_INTERACTIVO=true
	OPCION=""

	case "$1" in
		--no-interactivo )
			echo "Formateando en modo no interactivo"
			MODO_INTERACTIVO=false
			;;
		* )
			MODO_INTERACTIVO=true
			;;
	esac


	if [[ $MODO_INTERACTIVO == true ]]; then

		echo -e "\n----------------------------"
		echo "Se borrarán todos los archivos de $USB_DRIVE_SELEC"
		lsblk -o NAME,LABEL,SIZE,FSTYPE,PATH $USB_DRIVE_SELEC | sed "1d"
		echo -e "\n¿Está seguro de continuar? (s/N)"

		read OPCION
	else
		OPCION="S"
	fi

	case "$OPCION" in
		S|s )
				
			OPCION=""

			if [[ $MODO_INTERACTIVO == true ]]; then

				echo -e "\n----------------------------"
				echo "Este procedimiento de borrado no se puede deshacer"
				echo "Presione la tecla «C» para confirmar"

				read OPCION
			else
				OPCION="C"
			fi

			case "$OPCION" in
				C|c )
					
					NUM_PARTICIONES="$( lsblk $USB_DRIVE_SELEC | sed "1,2d" | wc -l )"

					

					echo -e "\n----------------------------"
					echo "Desmontando $USB_DRIVE_SELEC"

					if [[ $NUM_PARTICIONES -lt 1 ]]; then
						NUM_PARTICIONES=2
						sudo umount "${USB_DRIVE_SELEC}"
					else
						sudo umount "${USB_DRIVE_SELEC}"[1-"${NUM_PARTICIONES}"]
					fi
					
					echo "Borrando $USB_DRIVE_SELEC..."
					sudo sgdisk --clear "${USB_DRIVE_SELEC}" 1>/dev/null
					sudo sgdisk --zap-all "${USB_DRIVE_SELEC}" 1>/dev/null

					#echo "Ver debug"
					#read OPCION

					echo "Creando nueva tabla de particiones GPT en $USB_DRIVE_SELEC"
					echo "Creando partición EFI de $EFI_SIZE MiB"
					sudo sgdisk -n 1:1MiB:"${EFI_SIZE}"MiB "${USB_DRIVE_SELEC}" 1>/dev/null
					echo "Creando segunda partición con el resto del espacio disponible"
					sudo sgdisk -n 2 "${USB_DRIVE_SELEC}" 1>/dev/null

					#echo "Ver debug"
					#read OPCION

					sudo umount "${USB_DRIVE_SELEC}"[1-"${NUM_PARTICIONES}"] 2>/dev/null

					sudo sgdisk -t 1:ef00 "${USB_DRIVE_SELEC}" 1>/dev/null
					sudo sgdisk -t 2:0700 "${USB_DRIVE_SELEC}" 1>/dev/null

					#echo "Ver debug"
					#read OPCION

					sudo umount "${USB_DRIVE_SELEC}"[1-"${NUM_PARTICIONES}"] 2>/dev/null

					echo "Estableciendo etiquetas a las particiones"
					echo "Primera partición: ${ETIQUETA_PARTICION1}"
					sudo sgdisk -c 1:"${ETIQUETA_PARTICION1}" "${USB_DRIVE_SELEC}" 1>/dev/null
					echo "Segunda partición: ${ETIQUETA_PARTICION2}"
					sudo sgdisk -c 2:"${ETIQUETA_PARTICION2}" "${USB_DRIVE_SELEC}" 1>/dev/null

					#echo "Ver debug"
					#read OPCION

					sudo umount "${USB_DRIVE_SELEC}"[1-"${NUM_PARTICIONES}"] 2>/dev/null

					sudo mkfs.vfat -n "${ETIQUETA_PARTICION1}" "${USB_DRIVE_SELEC}1"  1>/dev/null
					#sudo mkfs.ntfs -f -L "${ETIQUETA_PARTICION2}" "${USB_DRIVE_SELEC}2" 1>/dev/null
					sudo mkfs.exfat -n "${ETIQUETA_PARTICION2}" "${USB_DRIVE_SELEC}2" 1>/dev/null

					#echo "Ver debug"
					#read OPCION

					;;
				* )
					proc-cancelado
					;;
			esac

			;;
		* )
			proc-cancelado
			;;
	esac
}

montar_unidades () {

	PROBLEMAS=0

	echo -e "\n----------------------------"
	ISO_LOOP_CRUDO="$( udisksctl loop-setup  -r -f "${ISO_FILE}" )"
	if [[ $? -ne 0 ]]; then
		PROBLEMAS=1
	fi
	#echo "debug - ${ISO_LOOP_CRUDO} -> ${PROBLEMAS}"

	

	ISO_LOOP="$( echo "${ISO_LOOP_CRUDO}" | grep -oE '[^ ]+$' | sed "s|\.$||g" )"
	#echo "debug - ${ISO_LOOP} -> ${PROBLEMAS}"



	ISO_MONTAJE_CRUDO="$( udisksctl mount -b "${ISO_LOOP}" )"
	if [[ $? -ne 0 ]]; then
		PROBLEMAS=1
	fi
	#echo "debug - ${ISO_MONTAJE_CRUDO} -> ${PROBLEMAS}"


	ISO_MONTAJE="$( echo "${ISO_MONTAJE_CRUDO}" | grep -oE '[^ ]+$' | sed "s|\.$||g" )"
	echo "$( basename ${ISO_FILE}) montada en ${ISO_MONTAJE}"

	#Asegurarse de que las particiones estén desmontadas
	#echo "debug - Desmontando particiones de unidad ${USB_DRIVE_SELEC}"
	sudo umount "${USB_DRIVE_SELEC}"[1-5] 2>/dev/null
	
	USB_EFI_MONTAJE_CRUDO="$( udisksctl mount -b "${USB_DRIVE_SELEC}1" )"
	if [[ $? -ne 0 ]]; then
		PROBLEMAS=1
	fi
	#echo "debug - ${USB_EFI_MONTAJE_CRUDO} -> ${PROBLEMAS}"

	USB_EFI_MONTAJE="$( echo "${USB_EFI_MONTAJE_CRUDO}" | grep -oE '[^ ]+$' | sed "s|\.$||g" )"
	echo "${USB_DRIVE_SELEC}1 montada en ${USB_EFI_MONTAJE}"
	
	USB_INSTAL_MONTAJE_CRUDO="$( udisksctl mount -b "${USB_DRIVE_SELEC}2" )"
	if [[ $? -ne 0 ]]; then
		PROBLEMAS=1
	fi
	#echo "debug - ${USB_INSTAL_MONTAJE_CRUDO} -> ${PROBLEMAS}"


	USB_INSTAL_MONTAJE="$( echo "${USB_INSTAL_MONTAJE_CRUDO}" | grep -oE '[^ ]+$' | sed "s|\.$||g" )"
	echo "${USB_DRIVE_SELEC}2 montada en ${USB_INSTAL_MONTAJE}"

	#echo "debug - Problemas: ${PROBLEMAS}"

	#echo "Ver debug"
	#read OPCION

	return ${PROBLEMAS}
}

desmontar_unidades () {

		echo -e "\n----------------------------"
	echo "Desmontando unidades"
	echo "Desmontando $( basename ${ISO_FILE})"
	udisksctl unmount -b "${ISO_LOOP}" 1>/dev/null
	udisksctl loop-delete -b "${ISO_LOOP}" 1>/dev/null

	echo "Desmontando ${USB_EFI_MONTAJE}"
	echo "Escribiendo datos del cache a la unidad de almacenamiento USB"
	udisksctl unmount -b "${USB_DRIVE_SELEC}1" 1>/dev/null
	
	echo "Desmontando ${USB_INSTAL_MONTAJE}"
	echo "Escribiendo datos del cache a la unidad de almacenamiento USB"
	udisksctl unmount -b "${USB_DRIVE_SELEC}2" 1>/dev/null
}

copy-files () {

	

	montar_unidades

	ESTADO="$?"

	#echo "debug - Estado: $ESTADO"

	#echo "Ver debug"
	#read OPCION

	if [[ $ESTADO -ne 0 ]]; then

		echo -e "\n----------------------------"
		echo "** Error - No se pudo montar alguna de las particiones **"
		echo "El proceso de formateo se repetirá a continuación"

		desmontar_unidades
		format-usb-drive --no-interactivo
		montar_unidades

		ESTADO="$?"

		#echo "debug - Estado: $ESTADO"
	fi

	if [[ $ESTADO -eq 0 ]]; then

		CARPETA_ORIGEN=$(pwd)
		cd "${ISO_MONTAJE}"

		echo -e "\nIniciando copia de archivos"
		rsync -rvh --progress $( ls | grep -v sources) "${USB_EFI_MONTAJE}/"
		mkdir -p "${USB_EFI_MONTAJE}/sources/"
		rsync -rvh --progress sources/boot.wim  "${USB_EFI_MONTAJE}/sources/"
		rsync -rvh --progress "${ISO_MONTAJE}/"  "${USB_INSTAL_MONTAJE}/"
		echo -e "\nCopia de archivos finalizada"

		cd "${CARPETA_ORIGEN}"
	else
		echo -e "\n----------------------------"
		echo -e "** Error - No se copiaron los archivos **\n"
		echo "No se pudo montar correctamente alguna de las particiones, lo más"
		echo "probable es que repetir el procedimiento solucione el problema."
		echo -e "\nPor favor vuelva a intentarlo."
	fi

	desmontar_unidades

	echo -e "\n----------------------------"
	echo "Proceso finalizado"
	proc-salir
}

bienvenida
selec-iso-file
get-usb-drives
selec-usb-drive
format-usb-drive
copy-files
