#!/usr/bin/env bash

cat <<-EOWarn
	This script is unmaintained and provided as-is. It may or may not work.

	Use at your own risk!
EOWarn

read -p "Press Enter to continue or Ctrl-C to abort"

declare -r				\
	DOCDIR=%DOCDIR%			\
	LIBDIR=%LIBDIR%			\
	SHAREDIR=%SHAREDIR%
declare -r				\
	exampleconf=$DOCDIR/example.cfg	\
	schema=$SHAREDIR/schema.sql	\
					\
	oldIFS="$IFS"

## Define exit codes
source "$SHAREDIR"/errorcodes

# config structures
declare -A			\
	destinationchannels	\
	destinationfat32compat	\
	destinationcopymime	\
	destinationformat	\
	destinationfrequency	\
	destinationid		\
	destinationloss		\
	destinationmaxbps	\
	destinationnormalize	\
	destinationpath		\
	destinationquality	\
	destinationrename	\
	destinationnoresample	\
	destinationrenamepath	\
	destinationskipmime	\
|| {
	echo "Check your Bash version. You need >= 4.0" >&2
	exit $EBASHVERS
}

LC_ALL=C

shopt -s extglob

for function in "$LIBDIR"/*/*
do
	source "$function"
done

if ! [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/AtOM/atom.cfg" ]]	\
&& [[ -f "$HOME/.atom/atom.cfg" ]]
then
	echo	"Configuration found in legacy location $HOME/.atom/atom.cfg."\
		"Migrating configuration and data to XDG standard"
	xdgMigrate
fi
cffile="${XDG_CONFIG_HOME:-$HOME/.config}/AtOM/atom.cfg"

while getopts 'urnD' opt
do
	case $opt in
		u)	update=1	;;
		r)	rename=1	;;
		n)	pretend=1	;;
		D)	(( debug++ ))	;;
	esac
done

getConfig

sanityCheck
openDatabase

(( update )) && getFiles

echo '
	SELECT
		source_files.id,
		source_files.filename,
		mime_types.mime_text
	FROM
			source_files
	INNER JOIN	mime_types
		ON	source_files.mime_type = mime_types.id
	;
	SELECT	"AtOM:NoMoreFiles";
' >&3

getdstfiles() {
	local		\
		line	\
		lines
	unset dest
	for destination in "${!destinationformat[@]}"
	do
		if [[ ${destinationformat["$destination"]} != $format ]]
		then
			continue
		fi
		echo '
			SELECT
				destination_files.id,
				destination_files.filename
			FROM		destination_files
			INNER JOIN	source_files
				ON
				destination_files.source_file_id=source_files.id
			INNER JOIN	destinations
				ON
				destinations.id=destination_files.destination_id
			WHERE	source_files.id='$fileid'
			AND	destinations.name="'"$destination"'"
			AND	destination_files.filename IS NOT NULL
			AND	destination_files.filename NOT LIKE
					"%'$extension'"
			;
			SELECT	"AtOM:NoMoreFiles";
		'>&3
		while read -u4 -r -d $'\0' line
		do
			if [[ $line == AtOM:NoMoreFiles ]]
			then
				break
			fi
			lines+=("$line")
		done
	done
	for line in "${lines[@]}"
	do
		fileid=${line%::AtOM:SQL:Sep::*}
		filename=${line#*::AtOM:SQL:Sep::}
		echo $'\t'"$filename"
		(( rename )) && echo -n $'\t'
		(( rename )) && renameFile
	done
}

renameFile() {
	echo " -> ${filename%.*}$extension"
	if ! (( pretend ))
	then
		if [[ $dest == '' ]]
		then
			table=destination_files
		else
			table=source_files
		fi
		mv							\
			"${dest:+$dest/}$filename"			\
			"${dest:+$dest/}${filename%.*}$extension"	\
		&& Update $table filename "${filename%.*}$extension"<<-EOW
			id = $fileid
		EOW
	fi
}

while read -u4 -r -d $'\0' line
do
	if [[ $line == AtOM:NoMoreFiles ]]
	then
		break
	fi
	lines+=("$line")
done
for line in "${lines[@]}"
do
	fileid=${line%%::AtOM:SQL:Sep::*}
	rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
	filename=${rest%%::AtOM:SQL:Sep::*}
	rest=${rest#*::AtOM:SQL:Sep::}
	mimetype=${rest%%::AtOM:SQL:Sep::*}
	rest=${rest#*::AtOM:SQL:Sep::}
	dest=$sourcepath
	case "$mimetype" in
		'audio/mpeg')
			if [[ ${filename##*.} != mp3 ]]
			then
				format=mp3
				extension=.mp3
				echo "$filename: MP3 ($extension)"
				(( rename )) && renameFile
				getdstfiles
			fi
		;;
		'application/ogg vorbis')
			if [[ ${filename##*.} != ogg ]]
			then
				format=vorbis
				extension=.ogg
				echo "$filename: Ogg Vorbis ($extension)"
				(( rename )) && renameFile
				getdstfiles
			fi
		;;
		'application/ogg opus')
			if [[ ${filename##*.} != opus ]]
			then
				format=opus
				extension=.opus
				echo "$filename: Opus ($extension)"
				(( rename )) && renameFile
				getdstfiles
			fi
		;;
		'audio/x-flac')
			if [[ ${filename##*.} != flac ]]
			then
				format=flac
				extension=.flac
				echo "$filename: FLAC ($extension)"
				(( rename )) && renameFile
			fi
		;;
		'application/data')
			extendedtype=$(file -b "$sourcepath/$filename")
			[[ $extendedtype =~ Musepack ]] || continue
			if [[ ${filename##*.} != flac ]]
			then
				format=mpc
				extension=.mpc
				echo "$filename: Musepack ($extension)"
				(( rename )) && renameFile
			fi
		;;
	esac
done

closeDatabase
