#!/bin/sh

set -e

anki_connect="localhost:8765"
afield="sent_a"
aext="ogg"
ifield="img"
iext="avif"
sfield="sent"
rfield="sent_r"

: ${TMPDIR:=/tmp}
lock="$TMPDIR/ankiupdatelock"

log() {
  notify-send "anki-update: $1"
  printf "\e[33m%s\e[0m\n" "$1"
}
fail() {
  log "$1"
  bell
  exit 1
}
anki() {
  curl -s "$anki_connect" -X POST -d "$(printf '{"action":"%s","version":6,"params":%s}' "$1" "$2")"
}
stop_record() {
  kill "$pid2"
  inotifywait -e close_write "$audio" -qq
}
screenshot() {
  window="$(xprop -root | sed -n 's/^_NET_ACTIVE_WINDOW(WINDOW): window id # //p')"
  maim -u -i "$window" | ffmpeg -loglevel error -i - -vf scale=-1:200 "$image"
  tag="$(xprop -id "$window" | sed -n 's/^WM_NAME(STRING) = "\(.*\)"$/\1/p' | tr ' ' _)"
  echo "* tag: $tag"
}
get_latest() {
  id="$(anki findNotes '{"query":"added:1"}')" || fail "anki connect unreachable"
  id="$(echo "$id" | jq .result[-1])"
  if [ "$id" = "null" ]; then
    fail "no note to update"
  fi
}
get_note_field() {
  note="$(anki notesInfo "$(printf '{"notes":[%d]}' "$id")")"
  old_sent="$(echo "$note" | jq -r .result[0].fields.['"'"$sfield"'"'].value)"
  echo "* old sentence: $old_sent"
  old_term="${old_sent%%</b>*}"
  old_term="${old_term##*<b>}"
  echo "* old term: $old_term"
}
get_name() {
  date="$(date +%Y_%m_%d-%H_%M_%S)"
  aname="$tag-$date.$aext"
  iname="$tag-$date.$iext"
}
get_reading() {
  sent="$(xclip -o -sel clip)"
  echo "* clipboard: $sent"
  case "$sent" in
    *"$old_term"*) ;;
    *) fail "clipboard does not contain term" ;;
  esac
  reading="$(furigana "$sent")"
  sent="$(echo $sent | a="$old_term" pyp -b 's=os.environ["a"]' 'x.replace(s, "<b>%s</b>"%s)')"
  echo "* new sentence: $sent"
  echo "* reading: $sent"
}
update() {
  anki updateNote "$(printf '{"note":{
    "id":%d,
    "tags":"%s",
    "fields":{"%s":"%s","%s":"%s"},
    "picture":{
      "filename":"%s",
      "path":"%s",
      "fields":["%s"]
    }%s
  }}' "$id" "$tag" "$sfield" "$sent" "$rfield" "$reading" "$iname" "$image" "$ifield" "$1")"
  log "updated note $id"
}

if [ "$1" = "-s" ]; then
  image="$TMPDIR/img-$$.$iext"
  trap "rm '$image'" EXIT

  get_latest
  screenshot
  get_note_field
  get_name
  get_reading
  update
elif [ "$1" = "-x" ]; then
  [ -e "$lock" ] || fail "not running"
  IFS=, read pid1 pid2 id < "$lock"
  kill "$pid2"
  audio="$TMPDIR/aud-$pid1.$aext"
  rm "$audio" "$lock"
  log "cancelled anki update"
elif ! [ -e "$lock" ]; then
  get_latest
  log 'recording started'
  record-audio \
    -af silenceremove=1:0:-50dB \
    "$TMPDIR/aud-$$.$aext" &
  echo "$$,$!,$id" > "$lock"
else
  IFS=, read pid1 pid2 id < "$lock"
  audio="$TMPDIR/aud-$pid1.$aext"
  image="$TMPDIR/img-$pid1.$iext"
  trap "rm '$audio' '$image' '$lock'" EXIT

  log "stopping recording"
  stop_record
  screenshot
  get_note_field
  get_name
  get_reading
  update "$(printf ', "audio":{
    "filename":"%s",
    "path":"%s",
    "fields":["%s"]
  }' "$aname" "$audio" "$afield")"
fi
