#!/bin/sh
# v1.0
# NEd: Note Editor (and your best friend!)
# Ned can edit and create notes in a folder you tell him to!
# Depends: fzf

# TODO: make it so the script assumes you are editing, and automatically creates a new document if the file to edit doesn't exist

# shellcheck disable=SC2068,SC2178,SC2128

# set default values if things are unset
BASE_DIR="${NOTES_DIR:-"$HOME/Documents/college/current"}"
EDITOR="nvim"
EDITOR_CMD="nvim -c :ZenMode"
DEFAULT_NEW_NOTE_EXT=.md
DEFAULT_NEW_NOTE_NAME="$(date +'%m-%d')$DEFAULT_NEW_NOTE_EXT"

# Some fzf commands
FZF="fzf -1 --layout=reverse --info=inline --height=10%"

usage() {
   cat <<-EOF
		Usage:
		ned <verb>
		   new <folder> [note name]        Create a new note in the matched folder
		   [edit|ed] [folder] <note name>  Search for and edit a text document in a folder
		   ned                             Edit ned
		   help                            Print this message
		   cd [folder]                     Open a shell in a directory or the default directory

		Notes:
		   Edit 'T' to get today's note
		   Folder and file names are searched with fuzzy search
		   ned will automatically activate the ZenMode neovim extension
		   Current repository path: '$BASE_DIR'
	EOF
}

open_file() {
   cd "$(dirname "$1")" || return
   $EDITOR_CMD "$1"
}

# Usage:
#        edit "unused param" ["search_directory"] "search_term"
edit() {
   check_setup

   # This logic is to allow $2 to be optional
   if [ -n "$3" ]; then
      SEARCH_TERM="$3"
      NOTE_DIR="$BASE_DIR/$(cd "$BASE_DIR" && fd -t d -d 1 | sed 's-\./--g' | $FZF -q "$2")" || exit
   elif [ -n "$2" ]; then
      SEARCH_TERM="$2"
   else
      echo "$0: Error: No file specified" && usage && exit
   fi

   # Searching for 'T' will get you today's note
   if [ "$SEARCH_TERM" = 'T' ]; then
      SEARCH_TERM="$DEFAULT_NEW_NOTE_NAME"
   fi

   NOTE="$NOTE_DIR/$(cd "$NOTE_DIR" && $FZF -q "$SEARCH_TERM")" || exit

   open_file "$NOTE"
}

# Usage: new "unused param" "save directory" ["note name"]
new() {
   check_setup

   # Note name
   if [ -n "$3" ]; then
      NEW_NOTE_NAME="$3"
   else
      NEW_NOTE_NAME="$DEFAULT_NEW_NOTE_NAME"
   fi
   # TODO: what if there is no $2 provided

   # Note dir
   NEW_NOTE_DIR="$BASE_DIR/$(cd "$BASE_DIR" && fd -t d -d 1 | sed 's-\./--g' | $FZF -q "$2")/notes" || exit

   # make the directory if it doesn't exist
   [ -d "${NEW_NOTE_DIR}" ] || mkdir "${NEW_NOTE_DIR}"

   if [ -f "$NEW_NOTE_DIR/$NEW_NOTE_NAME" ]; then
      open_file "$NEW_NOTE_DIR/$NEW_NOTE_NAME"
   else
      cd "$NEW_NOTE_DIR" || exit
      # apply a template for notes
		cat <<-EOF >> "$NEW_NOTE_DIR/$NEW_NOTE_NAME"
			# ${NEW_NOTE_NAME%%"$DEFAULT_NEW_NOTE_EXT"}

			<!-- vim: wrap nonu nornu
			-->
		EOF
      STARTING_MD5="$(md5sum "$NEW_NOTE_DIR/$NEW_NOTE_NAME")"
      open_file "$NEW_NOTE_DIR/$NEW_NOTE_NAME"
      # Delete the file if no changes were made
      if [ "$(md5sum "$NEW_NOTE_DIR/$NEW_NOTE_NAME")" = "$STARTING_MD5" ]; then
         rm "$NEW_NOTE_DIR/$NEW_NOTE_NAME"
      fi
   fi
}

subshell() {
   echo
   echo 'entering subshell'
   $SHELL
}

shell() {
   if [ -n "${2+foo}" ]; then
      DIR="$BASE_DIR/$(cd "$BASE_DIR" && fd -d 1 -t d | sed 's-\./--g' | $FZF -q "$2")" || exit
   else
      DIR="$BASE_DIR"
   fi
   if cd "$DIR"; then
      subshell
   else
      exit
   fi
}

check_setup() {
   # perform preliminary checks to make sure the script can run properly
   if ! [ -d "$BASE_DIR" ]; then
      echo "Error: Notes directory ($BASE_DIR) does not exist or is not a directory"
      exit 1
   fi
}

# Parse arguments (first character only)
case "${1}" in
   # help
   '--help'|'-h'|'help'|'h') usage;;
   # create and edit new note
   'new') new $@;;
   # edit an existing document or file
   'edit'|'ed') edit $@;;
   # run a shell (cd to) in the directory
   'cd') shell $@;;
   # edit ned (the file you are looking at right now)
   'ned') $EDITOR "$(realpath "$0")";;
   *) echo "no such option";;
esac

# vim: et sw=3 ts=3 ft=sh