#!/bin/bash
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
# this one liner from the man page of flock makes sure we only run one instance, this code is as concise as it gets
# this script should only run once at a time, to prevent fuckups in the renaming
function dep_check()
{
	for dependency in ffprobe
	do
		type "$dependency" >/dev/null 2>&1 || { echo "I require "$dependency" but it's not installed.  Aborting."; exit 1; }
	done
	return
}
dep_check
if [ -z "$1" -o -z "$2" ]; then
	echo -e "tag2name: rename mp3 and ogg files according to the tag information found in the file"
	echo -e "usage: ./tag2name.sh source_dir target_dir mode"
	echo -e "where mode can be either copy (copies the files to target dir) or move (moves the files to target dir)"
	echo -e "example: ./tag2name.sh ../music ../new_music copy"
	echo -e "omitting the third parameter (mode) will just list the old and new filenames, but not actually do anything"
	echo -e "USE AT OWN RISK; CODE IS EXPERIMENTAL"
	exit 0
fi
# checking directory to read
if [[ ! -r "$1" ]]; then
	echo "source directory (first parameter given = $1) is not readable, exiting"
	exit 0
fi
# checking directory to write
if [[ ! -w "$2" ]]; then
	echo "target directory (second parameter) is not writable, exiting"
	exit 0
fi
for dir in "$1"/*
	do
		mapfile -t ut_files < <( find "$dir" -type f -iname "*.mp3" -o -iname "*.ogg")
		for filename in "${ut_files[@]}"
			do 
				tag_info=$(ffprobe -hide_banner -format flat "$filename" -show_entries format_tags=artist -show_entries format_tags=album -show_entries format_tags=track -show_entries format_tags=title -show_entries format_tags=date -show_entries format_tags=disc | sed -e 's/\[FORMAT\]\(.*\)\[\\FORMAT\]/\1/')
				artist=$(echo "$tag_info" | grep 'artist' | cut -f2 -d'=' | sed -e 's/ü/ue/gI' -e 's/ä/ae/gI' -e 's/ö/oe/gI' -e 's/ß/ss/gI' -e 's/[^a-zA-Z0-9._]/_/g')
				album=$(echo "$tag_info" | grep 'album' | cut -f2 -d'=' | sed -e 's/ü/ue/gI' -e 's/ä/ae/gI' -e 's/ö/oe/gI' -e 's/ß/ss/gI' -e 's/[^a-zA-Z0-9._]/_/g')
				track=$(echo "$tag_info" | grep 'track' | cut -f2 -d'=' | cut -f1 -d'/' | sed 's/[^0-9]//g')
				title=$(echo "$tag_info" | grep 'title' | cut -f2 -d'=' | sed -e 's/ü/ue/gI' -e 's/ä/ae/gI' -e 's/ö/oe/gI' -e 's/ß/ss/gI' -e 's/[^a-zA-Z0-9._]/_/g')
				year=$(echo "$tag_info" | grep 'date' | cut -f2 -d'=' | cut -c 1-4 | sed 's/[^0-9]//g')
				disc=$(echo "$tag_info" | grep 'disc' |cut -f2 -d'=' | cut -f1 -d'/' | sed 's/[^0-9]//g')
				extension=$(echo "$filename" | rev | cut -f1 -d'.' | rev)
				if [ "$track" != "" ] && [ "$track" -lt 10 ]; then
					track=$(echo "0$track")
				fi
				if [ "$artist" != "" ] && [ "$title" != "" ]; then
					if [[ ! -r "$2/$artist" ]]; then
						mkdir "$2/$artist"
					fi
					new_filename=$(echo "$artist"'-'"$year"'-'"$album"'-'"$disc"'-'"$track"'-'"$title"'.'"$extension" | sed -e 's/_-_/_/g' -e 's/-_/_/g' -e 's/--/-/g' -e 's/_\./\./g' -e 's/\.\./\./g' -e 's/___/_/g' -e 's/__/_/g' )
					check_lb=$(echo "$new_filename" | sed ':a;N;$!ba;s/\n//g')
					if [ -z "$check_lb" ]; then
						echo "no linebreaks found in $new_filename" >> "$2/tag2name_filemapping.txt"
					else
				    	echo "linebreaks found, changing to $check_lb" >> "$2/tag2name_filemapping.txt"
						new_filename=$(echo "$check_lb")
					fi
					if [ -n "$new_filename" ]; then
						if [ -r "$2/$artist/$new_filename" ]; then
							echo "file $2/$artist/$new_filename exists already, not doing anything" >> "$2/tag2name_file_existing.txt"
						elif [ "$3" == "copy" ]; then
							cp "$filename" "$2/$artist/$new_filename" && echo "copied file $filename to $2/$artist/$new_filename" >> "$2/tag2name_file_copied.txt"
						elif [ "$3" == "move" ]; then
							cp "$filename" "$2/$artist/$new_filename"
							if [ -r "$2/$artist/$new_filename" ]; then
								rm "$filename" && echo "moved $filename to $2/$artist/$new_filename" >> "$2/tag2name_file_moved.txt"
							else
								echo "something went wrong with moving file $filename" >> "$2/tag2name_errorlog,txt"
							fi
						else
						echo "mapping $filename to $2/$artist/$new_filename" >> "$2/tag2name_filemapping.txt"
						fi
					else
						echo "something went wrong with renaming file $filename" >> "$2/tag2name_errorlog,txt"
					fi
				else
					echo "no tags found in $filename" >> "$2/tag2name_no_tags.txt"
				fi
			done
	done

</div>