#!/usr/bin/env sh
# Read wallabag articles from the commandline
# extended version of one-liner script to read wallabag articles in shell
# "wallabag list -n | head -n-1 | tail -n+2 | fzf | sed -e 's/^ //' |  cut -f1 -d' ' | xargs wallabag show | ifne less"

WALLR_FILTER=${WALLR_FILTER:-all}
WALLR_READER=${WALLR_READER:-$PAGER}
WALLR_FZF_OPTS=${WALLR_FZF_OPTS:-"--border"}
WALLR_MARKREAD=true

# get listing of all (read/unread/starred/all) wallabag articles
get_articles() {
  WALLR_article_listing=""
  if [ "$WALLR_FILTER" = "all" ]; then
    WALLR_article_listing=$(wallabag list)
  elif [ "$WALLR_FILTER" = "starred" ]; then
    WALLR_article_listing=$(wallabag list -s)
  elif [ "$WALLR_FILTER" = "unread" ]; then
    WALLR_article_listing=$(wallabag list -n)
  elif [ "$WALLR_FILTER" = "last" ]; then
    WALLR_article_listing=$(wallabag list -q 1)
  else
    WALLR_article_listing=$(wallabag list -r)
  fi
  echo "$WALLR_article_listing" | head -n-1 | tail -n+2
}

# list articles and choose with fzf
fuzzy_select() {
  [ -z "$1" ] && exit 1
  echo "$1" | fzf "${WALLR_FZF_OPTS}"
}

# strip off only ID article listing
get_id() {
  [ -z "$1" ] && exit 1
  echo "$1" | sed -e 's/^ \+//' | cut -f1 -d' '
}

# grab content of article with ID passed in as parameter
get_content() {
  [ -z "$1" ] && exit 1
  wallabag show "$1" | tail -n+2
}

# open article in browser
open_link() {
  [ -z "$1" ] && exit 1
  wallabag open "$1"
}

# mark article read
mark_read() {
  [ -z "$1" ] && exit 1
  wallabag update --read "$1"
}

check_missing_reqs() {
  if command -v fzf >/dev/null && command -v wallabag >/dev/null; then
    false
  else
    true
  fi
}

open_in_pager() {
  get_content "$1" | "$WALLR_READER"
}

main() {
  # already selected an id
  if [ -n "$WALLR_ARTICLE_SELECTED" ]; then
    # relative selection
    if printf "%s" "$WALLR_ARTICLE_SELECTED" | grep -qe '^+'; then
      WALLR_FILTER="last"
      newestid=$(get_id "$(get_articles)")
      id=$((newestid - "$WALLR_ARTICLE_SELECTED"))
    fi
  # select with fuzzy menu
  else
    arts=$(get_articles "$WALLR_FILTER")
    art="$(fuzzy_select "$arts")"
    id="$(get_id "$art")"
  fi

  if [ "$WALLR_READER" = "BROWSER" ]; then
    open_link "$id"
  else
    open_in_pager "$id"
    if "$WALLR_MARKREAD"; then
      mark_read "$id"
    fi
  fi
}

show_help() {
  printf "%s\n" \
    "" \
    " reader       Read wallabag articles in the terminal." \
    "" \
    " Usage: reader [-horqsen] " \
    "" \
    " Options:" \
    "" \
    "     -o                                  Open selected file in browser." \
    "" \
    "     -e                                  Open selected file in editor." \
    "" \
    "     -r                                  List only read articles." \
    "" \
    "     -s                                  List only starred articles." \
    "" \
    "     -n                                  List only unread articles." \
    "" \
    "     -a [number]                         Do not list articles but directly open article number." \
    "                                         Takes either explicit number (1096 opens wallabag article" \
    "                                         with same id), or in the form of '+1' or '+102' which will" \
    "                                         open most recent counting backwards." \
    "" \
    "     -q                                  Do not mark articles opened as read." \
    "" \
    "     -h                                  Print out this help." \
    ""
}

while getopts "h?qnorsea:" opt; do
  case "$opt" in
  h | \?)
    show_help
    exit 0
    ;;
    # v)  verbose=1
    # ;;
  n)
    WALLR_FILTER="unread"
    ;;
  r)
    WALLR_FILTER="read"
    ;;
  s)
    WALLR_FILTER="starred"
    ;;
  e)
    WALLR_READER="$EDITOR"
    ;;
  o)
    WALLR_READER="BROWSER"
    ;;
  q)
    WALLR_MARKREAD="false"
    ;;
  a)
    WALLR_ARTICLE_SELECTED="$OPTARG"
    ;;
  esac
done
shift $((OPTIND - 1))

if check_missing_reqs; then
  echo "Requires wallabag-cli and fzf executable on path to work." 1>&2
  exit 1
fi
main "$@"
