#!/bin/bash

# BASIC INITIALIZATIONS

shopt -s nullglob globstar

set -e

# An array of all the variables we've created
declare -a CONTATE_TEMP_FILE_LIST

# contate_clean is a function to delete those temps and call dictionary's clean too, which celetes the variable temp

dbg "top-ish of main"
d_start
dbg "trap contate_clean()"
trap d_clean EXIT

# SET VARIABLES

[ -z "${CONTATE_RECURSE}" ] && CONTATE_RECURSE=false
[ -z "${CONTATE_QUIET}" ] && CONTATE_QUIET=false
[ -z "${CONTATE_PATTERN}" ] && CONTATE_PATTERN='(.*).contate$'
[ -z "${CONTATE_DRY}" ] && CONTATE_DRY=false
export CONTATE_QUIET CONTATE_RECURSE CONTATE_PATTERN CONTATE_OUTPUT CONTATE_DRY

while getopts ":o:p:c:dqrh" opt; do
	dbg "Getopts iteration"
	case "$opt" in
	c)
		CONTATE_CONFIG="$OPTARG"
		;;
	d)
		CONTATE_DRY=true
		;;
	o)
		CONTATE_OUTPUT="${OPTARG}"
		if [ "$CONTATE_OUTPUT" = "-" ]; then
			CONTATE_OUTPUT="/dev/stdout"
		fi
		;;
	r)
		CONTATE_RECURSE=true
		;;
	p)
		CONTATE_PATTERN="${OPTARG}"
		;;
	q)
		CONTATE_QUIET=true
		;;
	h)
		CONTATE_QUIET=false
		usage
		exit 0
		;;
	*)
		err	"Unkown opt: $OPTARG"
		usage 
		exit 1
		;;
	esac
done

dbg "All arguments passed:: ${*}"	

shift "$(( OPTIND - 1 ))"

dbg "CONTATE_DRY=${CONTATE_DRY}"
dbg "COTATE_CONFIG=${CONTATE_CONFIG}"
dbg "CONTATE_OUTPUT=${CONTATE_OUTPUT}"
dbg "CONTATE_RECURSE=${CONTATE_RECURSE}"
dbg "CONTATE_DEBUG=${CONTATE_DEBUG}"
dbg "CONTATE_QUIET=${CONTATE_QUIET}"
dbg "CONTATE_PATTERN=${CONTATE_PATTERN}"
dbg "CONTATE FILES: ${*}"

# VALIDATE FLAGS
validate_input() {
	if ${CONTATE_QUIET} && ${CONTATE_DEBUG}; then
		err "You cannot set both quiet and debug"
		exit 1
	fi

	if [[ -d "${CONTATE_OUTPUT}" ]]; then
		if [[ -w "${CONTATE_OUTPUT}" ]]; then
			dbg "CONTATE_OUTPUT is a directory"
			CONTATE_OUTPUT="$(realpath "${CONTATE_OUTPUT}")"
		else
			err "Can't write to ${CONTATE_OUTPUT}"
			exit 1
		fi
	elif [ -z "${CONTATE_OUTPUT}" ] || [ "${CONTATE_OUTPUT}" = "/dev/stdout" ]; then
		dbg "CONTATE_OUTPUT not set, so stdout"
		CONTATE_OUTPUT="/dev/stdout"
	else
		err "Contate cannot currently create directories or use a custom naming scheme for files beyond -p"
		usage
		exit
	fi
	dbg "CONTATE_OUTPUT reset to: ${CONTATE_OUTPUT}"

	if [ -n "${CONTATE_COBFIG}" ] && [ ! -d "${CONTATE_CONFIG}" ] && [ ! -f "${CONTATE_CONFIG}" ]; then
		err "-c Must set a file or directory"
		exit 1
	fi
	if [ -d "${CONTATE_CONFIG}" ]; then
		CONTATE_CONFIG="${CONTATE_CONFIG}/*"
		dbg "New CONTATE_CONFIG after directory expansion:"
		dbg "${CONTATE_CONFIG}"
	fi
}
validate_input

# RECURSE THROUGH INPUTS
recurse() {
	dbg "Passed to recurse: ${@}"
	for target; do
		if [[ -d "${target}" ]] && ! $CONTATE_RECURSE; then
			err "${target} is a directory but didn't specify -r"
			usage
			exit 1
		fi
	done
	for target; do
		dbg "Recurse is looping on ${target}"
		if [ "$D_MASTER" = "$$" ]; then
			if [ -f "$target" ]; then
				export REMOVABLE_PATH="$(dirname $(realpath $target))"/
			else
				export REMOVABLE_PATH="$(realpath $target)"/
			fi
			dbg "REMOVABLE_PATH: $REMOVABLE_PATH"
		fi
		if [[ -d "${target}" && -x "${target}" && -r "${target}" ]]; then
			dbg "TARGET DIRECTORY: ${target}"
			dbg recurse target: ${target}/*
			contate $(realpath ${target})/*
			must $? "Contate failed on one of $(realpath ${target})/*"
		elif [[ -f "${target}" && -r "${target}" ]]; then
			target="$(realpath $target)"
			dbg "TARGET FILE: ${target}"
			if [[ "${target}" =~ ${CONTATE_PATTERN} ]]; then
				if [ "${CONTATE_OUTPUT}" != "/dev/stdout" ] && [ "$SPECIFIC_OUTPUT" != "/dev/null" ]; then
					if [ -n "${BASH_REMATCH[1]}" ]; then
						dbg "Calculating output: "
						dbg "BASH_REMATCH: ${BASH_REMATCH[1]}"
						dbg "REMOVABLE_PATH: ${REMOVABLE_PATH}"
						OUTPUT_SUBPATH="${BASH_REMATCH[1]#${REMOVABLE_PATH}}"
					else
						dbg "Calculating output: "
						dbg "target: ${target}"
						dbg "REMOVABLE_PATH: ${REMOVABLE_PATH}"
						OUTPUT_SUBPATH="${target#${REMOVABLE_PATH}}"
					fi
					SPECIFIC_OUTPUT="${CONTATE_OUTPUT}/${OUTPUT_SUBPATH}"
					dbg "Is a contate file! it's output is: ${SPECIFIC_OUTPUT}"
					mkdir -p "$(dirname ${SPECIFIC_OUTPUT})"
				elif [ -z "${SPECIFIC_OUTPUT}" ]; then
					SPECIFIC_OUTPUT="${CONTATE_OUTPUT}"
				fi
				if ! $CONTATE_DRY; then 
					contate_file "${target}" "${SPECIFIC_OUTPUT}" 
					must $? "Contate file failed somewhere on ${target} to ${SPECIFIC_OUTPUT}"
				fi
			fi
		fi
	done
}
if [ -n "${CONTATE_CONFIG}" ]; then
	dbg "In contate config"
	export SPECIFIC_OUTPUT="/dev/null"
	recurse "${CONTATE_CONFIG}"
	unset SPECIFIC_OUTPUT
	unset CONTATE_CONFIG
fi

dbg "recurse targets: ${@}"
recurse "${@}"
