#compdef tp temprs

# Zsh completion for temprs/tp — temporary file stack manager

# Helper: list 1-based indices from the temprs stack
_tp_indices() {
  local master_file stack_dir
  stack_dir="${TEMPRS_DIR:-${TMPDIR:-/tmp}/temprs}"
  master_file="${stack_dir}/temprs-stack"
  [[ -r "$master_file" ]] || return
  [[ ! -s "$master_file" ]] && return

  local -a descriptions
  local i=1 filepath name_tag

  # The master record uses \0\0 as record delimiter and \0 as field delimiter.
  # Zsh variables cannot hold null bytes, so replace \0 with RS (\x1e) first:
  #   record delimiter \0\0 becomes \x1e\x1e, field delimiter \0 becomes \x1e
  local content RS=$'\x1e' RSRS=$'\x1e\x1e'
  content=$(tr '\0' "$RS" < "$master_file")
  [[ -z "$content" ]] && return

  local -a records
  records=("${(@ps:$RSRS:)content}")
  for record in "${records[@]}"; do
    [[ -z "$record" ]] && continue
    if [[ "$record" == *"$RS"* ]]; then
      filepath="${record%%"$RS"*}"
      name_tag="${record#*"$RS"}"
    else
      filepath="$record"
      name_tag=""
    fi
    [[ -z "$filepath" ]] && continue
    if [[ -n "$name_tag" ]]; then
      descriptions+=("${i}:${filepath:t} @${name_tag}")
      descriptions+=("${name_tag}:${filepath:t} [${i}]")
    else
      descriptions+=("${i}:${filepath:t}")
    fi
    (( i++ ))
  done

  _describe -t indices 'stack index' descriptions
}

_tp() {
  local -a args
  args=(
    '(-i --input)'{-i,--input}'[Write into tempfile at INDEX]:index:_tp_indices'
    '(-o --output)'{-o,--output}'[Read from tempfile at INDEX]:index:_tp_indices'
    '(-a --add)'{-a,--add}'[Insert tempfile at INDEX]:index:_tp_indices'
    '(-r --remove)'{-r,--remove}'[Remove tempfile at INDEX]:index:_tp_indices'
    '(-e --edit)'{-e,--edit}'[Open tempfile at INDEX in $EDITOR]:index:_tp_indices'
    '(-w --name)'{-w,--name}'[Tag tempfile with NAME]:name: '
    '(-R --rename)'{-R,--rename}'[Rename tag from OLD to NEW]:old name:_tp_indices:new name: '
    '(-I --info)'{-I,--info}'[Show metadata for tempfile at INDEX]:index:_tp_indices'
    '(-g --grep)'{-g,--grep}'[Search tempfile contents for PATTERN]:pattern: '
    '(-C --cat)'{-C,--cat}'[Concatenate tempfiles to stdout]:*:index:_tp_indices'
    '(-k --count)'{-k,--count}'[Print number of tempfiles on the stack]'
    '(-D --diff)'{-D,--diff}'[Diff two tempfiles]:file A:_tp_indices:file B:_tp_indices'
    '(-M --mv)'{-M,--mv}'[Move tempfile to another position]:from:_tp_indices:to:_tp_indices'
    '(-x --dup)'{-x,--dup}'[Duplicate tempfile onto top of stack]:index:_tp_indices'
    '(-S --swap)'{-S,--swap}'[Swap two tempfiles]:file A:_tp_indices:file B:_tp_indices'
    '(-A --append)'{-A,--append}'[Append stdin to tempfile at INDEX]:index:_tp_indices'
    '(--rev)'--rev'[Reverse the entire stack order]'
    '(--expire)'--expire'[Purge tempfiles older than HOURS hours]:hours: '
    '(--head)'--head'[Show first N lines of tempfile]:index:_tp_indices:lines: '
    '(--tail)'--tail'[Show last N lines of tempfile]:index:_tp_indices:lines: '
    '(--wc)'--wc'[Print line count of tempfile]:index:_tp_indices'
    '(--size)'--size'[Print byte size of tempfile]:index:_tp_indices'
    '(--sort)'--sort'[Sort stack by key]:key:(name size mtime)'
    '(--replace)'--replace'[Replace pattern in tempfile]:index:_tp_indices:pattern: :replacement: '
    '(--path)'--path'[Print file path of tempfile]:index:_tp_indices'
    '(-p --pop)'{-p,--pop}'[Pop from top of stack]'
    '(-u --unshift)'{-u,--unshift}'[Push to bottom of stack]'
    '(-s --shift)'{-s,--shift}'[Shift from bottom of stack]'
    '(-d --dir)'{-d,--dir}'[List temprs directory]'
    '(-m --master)'{-m,--master}'[List temprs master record file]'
    '(-l --list-files)'{-l,--list-files}'[List all tempfiles on the stack]'
    '(-n --list-files-numbered)'{-n,--list-files-numbered}'[List all tempfiles numbered on the stack]'
    '(-L --list-contents)'{-L,--list-contents}'[List all tempfile contents on the stack]'
    '(-N --list-contents-numbered)'{-N,--list-contents-numbered}'[List all tempfiles numbered with contents]'
    '(-q --quiet)'{-q,--quiet}'[Suppress output when creating tempfile]'
    '(-c --clear)'{-c,--clear}'[Purge all tempfiles from the stack]'
    '*'{-v,--verbose}'[Increase verbosity level]'
    '(-h --help)'{-h,--help}'[Print help]'
    '(-V --version)'{-V,--version}'[Print version]'
    '1::input file:_files'
  )

  _arguments -s -S $args
}

_tp "$@"
