#!/bin/bash
# imc.sh - image copy
# 2015 ed <irc.rizon.net>
# something something mit license
#
set -e
[ "x$2" == "x" ] &&
{
	echo
	echo 'requires 2 arguments'
	echo
	echo '1) op mode:'
	echo '   d, check for dupes'
	echo '   n, check for continuity'
	echo '   c, copy all images in folder'
	echo '   r, copy all images recursively'
	echo
	echo '2) target directory'
	echo
	exit 1
}

imagemask='jpg|jpeg|png|gif'
rm imc.todo.list 2>/dev/null || true
op="$1"
to="$2"
cpy=''

function getlatest()
{
	{
		# list target directory with fallback '0.jpg'
		echo '0.jpg'
		find "$to" -maxdepth 1 2>/dev/null || true
	} |

	# remove until final /
	sed 's_.*/__' |
	
	# numerical sort
	sort -n |

	# filter by number.whatever
	grep -E '^[0-9]+\.' |

	# return the number of the last entry
	tail -n 1 |
	sed 's/\./\n/' |
	head -n 1
}

cpy=''
doit=''

# copy single level
[ "x$op" == "xc" ] &&
{
	cpy='-maxdepth 1'
	doit=y
}

# copy recursively
[ "x$op" == "xr" ] &&
	doit=y

# and then
[ $doit ] &&
{
	find $cpy -type f |
	grep -E "\.($imagemask)$" > imc.todo.list

	echo -n 'Starting after '
	fid=$(getlatest)
	echo $fid
	
	# get number of files to copy
	remains=$(
		cat imc.todo.list |
		wc -l
	)
	
	# make sure target exists and has md5 list
	mkdir -p "$to"
	touch "$to/.md5"

	cat imc.todo.list |
	while read file
	do
		echo -n "$remains  $file "
		remains=$(( remains - 1 ))
		hash=$(
			md5sum -- "$file" |
			head -c 32
		)

		# check if exists
		grep -qE "$hash" "$to/.md5" &&
		{
			echo -e "\033[1;33m no\033[0m"
			continue
		}
		
		fid=$((fid+1))
		ext="$(
			echo "$file" |
			sed 's/\./\n/g' |
			tail -n 1
		)"

		# copy image + add md5sum
		cp -- "$file" "$to/$fid.$ext"
		echo "$hash  $fid.$ext" >> "$to/.md5"
		echo -e "\033[1;32m Copied\033[0m"
	done
	rm imc.todo.list
	echo 'done'
	exit 0
}

# check for dupes
[ "x$op" == "xd" ] &&
{
	echo -e '\033[1;33mRunning dupe check\033[0m'
	
	md5sum "$to/"* |
	sed 's_  .*/_  _' > "$to/.md5"

	cat "$to/.md5" |
	sort |
	uniq -d -w 32 |
	while read hash
	do
		echo "Removing $hash"
		fn="$(
			echo "$hash" |
			cut -c 35-
		)"
		rm "$to/$fn"
	done
	echo -e '\033[1;32mFinished checking for dupes.\033[0m'
	echo 'Run a continuity check if changes were made'
	exit 0
}

# check continuity
[ "x$op" == "xn" ] &&
{
	echo -e '\033[1;33mRunning continuity check\033[0m'
	tn=0
	find "$to" -maxdepth 1 |
	grep -E "\.($imagemask)$" |
	sed 's_.*/__' |
	sort -n > imc.cont.list
	
	# iterate over all existing files
	cat imc.cont.list |

	# remove everything until final slash
	sed 's_.*/__' |

	# filter to number.whatever
	grep -E '^[0-9]+\.' |

	# only keep number
	sed 's/\..*//' |

	while read fn
	do
		tn=$(( tn + 1 ))
		while [ $tn -lt $fn ]
		do
			# if tn and fn mismatch here,
			# pick the first file that still exists
			# off the end of the file list
			# and swap it up to tn
			tac imc.cont.list |
			while read repl
			do
				[ -e "$repl" ] &&
				{
					rnum=$(
						echo "$repl" |
						sed 's_.*/__;s/[^0-9].*//'
					)
					[ $rnum -le $tn ] &&
					{
						echo -e "\033[1;31mNO MORE SUBSTITUTE FILES WTF\033[0m"
						break
					}
					ext=$(
						echo "$repl" |
						sed 's/\./\n/g' |
						tail -n 1
					)
					echo "Moving $rnum.$ext to $tn.$ext"
					mv "$to/$rnum.$ext" "$to/$tn.$ext"
					break
				}
			done
			tn=$(( tn + 1 ))
		done
	done
	rm imc.cont.list
	echo -e '\033[1;32mFinished checking continuity.\033[0m'
	echo 'Run a dupe check to refresh md5 cache if changes were made'
	exit 0
}

echo 'wat'
