#!/usr/bin/env bash

input="${DIR_INPUT:-/mnt/elfstone/syncthing/Music}";
output="${DIR_OUTPUT:-/mnt/elfstone/auto/Music-Portable}";

export input;
export output;

temp_dir="$(mktemp --tmpdir -d "portable-music-copy-XXXXXXX")";

on_exit() {
	rm -rf "${temp_dir}";
}
trap on_exit EXIT;

# flac
# jpeg
# jpg
# mp3
# ogg
# pdf
# png
# stignore
# txt

# $1	Source
# $2	Target
do_downmux() {
	local source="${1}";
	local target="${2}";
	
	set +e;
	ffmpeg -hide_banner -loglevel warning -nostats -i "${source}" -map_metadata 0 -id3v2_version 4 -c:v copy -disposition:v:0 attached_pic -ar 44100 -b:a 256k -f mp3 "${target}";
	exit_code="${?}";
	if [[ "${exit_code}" -ne 0 ]] && [[ -f "${target}" ]]; then
		rm "${target}";
	fi
	return "${exit_code}";
}

# $1	Source
# $2	Target
do_copy() {
	local source="${1}";
	local target="${2}";
	
	echo -n "cp ";
	cp "${source}" "${target}";
}

# $1	Source
compress_image() {
	local source="${1}";
	
	temp_file_png="$(mktemp --tmpdir="${temp_dir}" XXXXXXX.png)";
	temp_file_jpeg="$(mktemp --tmpdir="${temp_dir}" XXXXXXX.jpeg)";
	
	convert "${source}" -resize 256x256\> "${temp_file_jpeg}" >&2 &
	convert "${source}" -resize 256x256\> "${temp_file_png}" >&2 &
	wait
	
	jpegoptim --quiet --all-progressive --preserve "${temp_file_jpeg}" >&2 &
	optipng -quiet -fix -preserve "${temp_file_png}" >&2 &
	wait
	
	read -r size_png _ < <(wc --bytes "${temp_file_png}");
	read -r size_jpeg _ < <(wc --bytes "${temp_file_jpeg}");
	if [[ "${size_png}" -gt "${size_jpeg}" ]]; then
		# JPEG is smaller
		rm -rf "${temp_file_png}";
		echo "${temp_file_jpeg}";
	else
		# PNG is smaller
		rm -rf "${temp_file_jpeg}";
		echo "${temp_file_png}";
	fi
}

# $1	filename
process_file() {
	local filename="${1}";
	local extension="${filename##*.}";
	
	local orig_destination="${output}/${filename}";
	local destination="${orig_destination}";
	
	echo -n "[file] ${filename}: ";
	
	local do_downmux=false;
	# Downmux, but only the bitrate is above 256k
	if [[ "${extension}" == "flac" ]] || [[ "${extension}" == "ogg" ]] || [[ "${extension}" == "mp3" ]]; then
		probejson="$(ffprobe -hide_banner -v quiet -show_format -print_format json "${filename}")";
		is_above_256k="$(echo "${probejson}" | jq --raw-output '(.format.bit_rate | tonumber) > 256000')";
		exit_code="${?}";
		if [[ "${exit_code}" -ne 0 ]]; then
			echo -n "ffprobe failed; falling back on ";
			do_downmux=false;
		elif [[ "${is_above_256k}" == "true" ]]; then
			do_downmux=true;
		fi
	fi
	
	if [[ "${do_downmux}" == "true" ]]; then
		echo -n "downmuxing/";
		destination="${orig_destination%.*}.mp3";
	fi
	
	case "${extension}" in 
		png|jpg|jpeg|JPG|JPEG )
			local compressed_image; compressed_image="$(compress_image "${filename}")";
			local compressed_extension="${compressed_image##*.}";
			destination="${orig_destination%.*}.${compressed_extension}";
			;;
	esac
	
	if [[ -f "${destination}" ]] || [[ -f "${orig_destination}" ]]; then
		echo "exists in destination; skipping";
		return 0;
	fi
	
	local destination_dir; destination_dir="$(dirname "${destination}")";
	if [[ ! -d "${destination_dir}" ]]; then
		mkdir -p "${destination_dir}";
	fi
	
	case "${extension}" in
		flac|mp3|ogg )
			# Use ffmpeg, but only if necessary
			if [[ "${do_downmux}" == "false" ]]; then
				do_copy "${filename}" "${orig_destination}";
			else
				echo -n "ffmpeg ";
				do_downmux "${filename}" "${destination}";
				exit_code="$?";
				if [[ "${exit_code}" -ne 0 ]]; then
					echo "failed, exit code ${exit_code}: falling back on ";
					do_copy "${filename}" "${orig_destination}";
				fi
			fi
			;;
		
		png|jpg|jpeg|JPG|JPEG )
			mv "${compressed_image}" "${destination}";
			;;
		
		* )
			do_copy "${filename}" "${destination}";
			;;
	esac
	echo "done";
}

export temp_dir;
export -f process_file;
export -f compress_image;
export -f do_downmux;
export -f do_copy;

cd "${input}" || { echo "Error: Failed to cd to input directory"; exit 1; };
find  -type f -print0 | nice -n20 xargs -P "$(nproc)" -0 -n1 -I{} bash -c 'process_file "{}"';

echo "[ ${SECONDS} ] Setting permissions";
chown -R root:root "${output}";
chmod -R 0644 "${output}";
chmod -R ugo+X "${output}";

echo "[ ${SECONDS} ] Portable music copy update complete";