#!/usr/bin/env bash

# This file contains functions relating to file operations such as new, edit and deleting files

newFile(){
	vecho "newFile $*"
	cd "$dataDir" || return
	# While there is a - at the begining
	local title="$*"
	if [ -z "$title" ]; then
		echo -n "Enter a title: "
		read -r title
	fi
	local filename
	filename="$(escapeFilename "$title.md")"
	[ -e "$filename" ] && die "$filename already exists"
	echo -e "---
Title: $title
Tags:
	-
---
" > "$filename"
	editFile "$filename"
}

addFile(){
	vecho "addFile $*"
	local copiedFile
	local subFolder=""
	local ext
	local file
	local filenameTitle
	local yaml
	local yamlBlock
	local yamlTitle
	while [[ $1 = -?* ]]; do
		case "$1" in
			--asset) mkdir -p "${dataDir}assets"; subFolder+="assets/" ;;
			--yaml-header) yaml="header" ;;
			--yaml-file) yaml="file" ;;
			*) die "invalid add option: '$1'." ;;
		esac
		shift
	done
	file="$1"
	[ -z "$file" ] && die "You must specify a file"
	[ -f "$file" ] || die "File $file not found"

	ext="${file##*.}"
	copiedFile="${file##*/}"

	# If the type of yaml entry hasn't been specified on the command line
	if [ -z "$yaml" ]; then
		# We want a header if it's markdown, otherwise a seperate file
		if [ "$ext" = "md" ]; then
			yaml="header"
		else
			yaml="file"
		fi
	fi


	[ -e "$dataDir$copiedFile" ] && die "File $copiedFile already exists"
	cp "$file" "$dataDir$subFolder$copiedFile"

	# The title as specified in yaml (or empty string)
	yamlBlock="$(getYamlBlock "$subFolder$copiedFile")"
	yamlTitle="$(getYamlTitle "$subFolder$copiedFile")"
	# The title generated from filename
	filenameTitle="$(echo "$copiedFile" | tr '_' ' ' | sed -E 's/\..[^.]+$//')"
	if [ -z "$yamlTitle" ] || [ "$yamlTitle" = "null" ]; then
		# If empty, generate the title from the filename
		yamlTitle="$filenameTitle"
	else
		# If the yaml title and the filename title are different, then use the yaml title
		if [ "$yamlTitle" != "$filenameTitle" ]; then
			local newFilename=$(escapeFilename "$yamlTitle").$ext
			echo mv "$dataDir$subFolder$copiedFile" "$dataDir$subFolder$newFilename"
			warn "File renamed from $copiedFile to "$newFilename
			copiedFile="$newFilename"
		fi
	fi


	yamlBlock="Title: $yamlTitle
$yamlBlock"


	if [ "$yaml" = "header" ]; then
		local tmpfile=$(mktemp)
		echo "---
$yamlBlock
---" > $tmpfile
		sed '1 { /^---/ { :a N; /\n---/! ba; d} }' "$dataDir$subFolder$copiedFile" >> "$tmpfile"
		mv "$tmpfile" "$dataDir$subFolder$copiedFile"
	else
		echo "$yamlBlock" > "$dataDir$subFolder$copiedFile.yaml"
	fi

	updateFileChange "$subFolder$copiedFile"


}

# Takes the filename as a parameter
editFile(){
	vecho "editFile $*"
	cd "$dataDir" || return
	local filename
	filename="$(findFile "$*")"
	[ ! -e "$filename" ] && exit 1
	"$editor" "$filename"
	updateFileChange "$filename"
}

# This is used to update the DB when a file is changed
# param1 is the file
updateFileChange(){
	vecho "updateFileChange $*"
	cd "$dataDir" || return
	local filename
	local directory=""
	local title
	local newFilename
	local filetype="normal"
	local ext
	filename="$(findFile "$*")"
	ext="${filename##*.}"
	[ ! -e "$filename" ] && die "No such file $1"
	if echo "$filename" | grep -q '^assets/'; then
		filetype="asset"
		directory="assets/"
	fi
	title="$(getYamlTitle "$filename")"
	newFilename="$directory$(escapeFilename "$title.$ext")"
	if [ "$filename" = "$newFilename" ]; then
		# The title hasn't changed
		# check if the file is in the DB
		if ! fileInDB "$filename"; then
			# If not, add it
			echo "INSERT INTO items (filename, title, type)
			VALUES ( '$(safeSQL "$filename")',
				'$(safeSQL "$title")', '$(safeSQL "$filetype")' );" |
			sqlite3 "${sqliteFile}"
		fi
		# Make sure all the tags are up to date
		getYamlTags "$filename" | assignTags "$filename"
		gitChange "$filename"
	else
		# The title has changed so we need to move the file
		if [ -e "$newFilename" ]; then
			# If the place we need to move it to already exists, die
			die -e "$newFilename already exists
$filename title changed
Please resolve manually"
		else
			mv "$filename" "$newFilename"
			[ -e "$filename.yaml" ] && mv "$filename.yaml" "$newFilename.yaml"
			if fileInDB "$filename"; then
				echo "UPDATE items
					SET (filename,title) =
					('$(safeSQL "$newFilename")','$(safeSQL "$title")')
					WHERE filename = '$(safeSQL "$filename")';" |
					sqlite3 "${sqliteFile}"
			else
				# We get here if the title was changed in the create process
				echo "INSERT INTO items (filename, title, type)
					VALUES ( '$(safeSQL "$newFilename")',
					'$(safeSQL "$title")', '$(safeSQL "$filetype")' );" |
				sqlite3 "${sqliteFile}"

			fi
			getYamlTags "$newFilename" | assignTags "$newFilename"
			gitChange "$filename" "$newFilename"
		fi
	fi
}

deleteFile(){
	vecho "deleteFile $*"
	cd "$dataDir" || return
	local filename
	local fileID
	local rsp
	filename="$(findFile "$*")"
	fileID="$(findFileId "$filename")"
	[ ! -e "$filename" ] && exit 1
	echo -n "Are you sure? [yN] "
	read -r rsp
	if [[ "$(echo "$rsp" | tr '[:upper:]' '[:lower:]')" = "y"* ]]; then
		rm "$filename"
		[ -e "$filename.yaml" ] && rm "$filename.yaml"
		# This deletes the file from the sql database and any tag links
		echo "DELETE FROM items
			WHERE id = '$(safeSQL "$fileID")';
			DELETE FROM links
			WHERE itemID = '$(safeSQL "$fileID")';" |
			sqlite3 --column --header "${sqliteFile}"
		gitChange "$filename"
	fi
}

viewFile(){
	vecho "viewFile $*"
	cd "$dataDir" || return

	local id="$*"
	local filename

	filename="$(findFile "$id")"

	"$pager" "$filename"
}