#compdef sccs admin cdc comb delta get help prs prt rmdel sact sccsdiff unget val what

(( $+functions[_sccs_files] )) ||
_sccs_files() {
  local dir=${PROJECTDIR:-~+}/${PREFIX##*/}/$finalpath

  compset -P '*/'
  _files -W $dir -g \*\(:s/s.//\) "$@"
}

local curcontext="$curcontext" state line
typeset -A opt_args
local subcmds ropt copt sfiles finalpath

subcmds=(
  admin cdc check clean comb create deledit delget delta diffs edit
  enter fix get help info print prs ptr rmdel sact sccsdiff tell
  unedit unget val what
)

ropt='-r+[specify sccs delta id]:sccs delta id'
copt='-c+[specify date]:date-stamp'
sfiles=':file:_sccs_files'

if [[ $service = sccs ]]; then
  _arguments -C -A "-*" \
    '-r[run with real and not effective user ID]' \
    '-d+[specify root prefix]:root prefix:_directories' \
    '-p+[specify subdirectory of history file]:path to history file:_directories' \
    '*::command:->subcmd' && return 0

  if (( CURRENT == 1 )); then
    _wanted commands expl 'sccs command' compadd -a subcmds
    return
  fi
  service="$words[1]"
  curcontext="${curcontext%:*}-$service:"
fi
finalpath="${opt_args[-p]:-SCCS}"

case $service in
  admin)
    _arguments "$ropt" "$sfiles" \
      '-b[force encoding of binary data]' \
      '-h[check structure of s.file]' \
      '-n[create a new history file]' \
      '-z[recompute file checksum]' \
      '-a+[add access for a user or group]:user or group:_users' \
      '-e+[erase access for a user or group]:user or group:_users' \
      '-d+[delete flag from file]:flag' \
      '-f+[set specified flag]:flag' \
      '-i+[initialise history from specified file]:file:_files' \
      '-m+[insert specified MR numbers into commentary]' \
      '-t+[insert descriptive text from specified file]:file:_files' \
      '-y+[specify comment for initial delta]'
  ;;
  cdc)
    _arguments "$ropt" "$sfiles" \
      '-m+[specify MR numbers to add/delete in delta comment]' \
      '-y+[specify the comment]:comment' \
  ;;
  check|info|tell)
    _arguments "$sfiles" \
      '-b[ignore branches]' \
      '(-U)-u+[restrict to files being modified by specified user]::user:_users' \
      '(-u)-U[restrict to files being modified by current user]'
  ;;
  clean)
    _arguments '-b[ignore branches]'
  ;;
  comb)
    _arguments "$sfiles" \
      '-o[access reconstructed file at delta to be created]' \
      '-s[generate script that will produce a report]' \
      '-p+[specify SID of oldest delta to preserve]:sccs delta id'
      '-c+[specify list of deltas to preserve]:sccs delta list'
  ;;
  sact|print) _sccs_files;;
  create|enter) _files;;
  deledit|delget|delta)
    _arguments '-s[silent]' '-y+[specify delta commentary]:comment'
  ;;
  diffs)
    _diff_options diff "$sfiles" "$ropt" "$copt" \
      '-C[output a context diff]'
  ;;
  edit|get)
    _arguments "$sfiles" "$ropt" "$copt" \
      '-e[retrieve for editing]' \
      '-k[retrieve writable copy without checking out]' \
      '-m[precede each line with the delta in which it was added]' \
      '-p[produce retrieved version on standard output]' \
      '-s[silent]'
  ;;
  fix) _arguments "$ropt" "$sfiles";;
  help)
    _alternative \
      "commands:sccs command:(${(j: :)subcmds})" \
      'message-codes:sccs message code:' 
  ;;
  prs)
    _arguments "$sfiles" "$ropt" "$copt" \
      '-a[include all deltas including those marked removed]' \
      '-e[display delta info for all deltas earlier than that specified]' \
      '-l[display delta info for all deltas later than that specified]' \
      '-d+[specify format of report]:data spec'
  ;;
  prt)
    _arguments "$sfiles" "$copt" \
      '-a[include all deltas including those marked removed]' \
      '-b[print the body of the s.file]' \
      '-d[print delta table entries]' \
      '(-d -i -u -f -t)-e[everything - imply other options]' \
      '-i[print serial numbers of included, excluded and ignored deltas]' \
      '-s[print first line only of delta table entries]' \
      '-t[print descriptive text held in s.file]' \
      '-u[print usernames of users allowed to make deltas]' \
      '-r+[exclude delta entries newer than date]:date-time' \
      '-y+[exclude delta entries prior to sid]'
    ;;
  rmdel) _arguments "$ropt" "$sfiles";;
  sccsdiff) _diff_options diff "$ropt" "$sfiles";;
  val)
    _arguments "$sfiles" "$ropt" \
      '-s[silent]' \
      '-m+[compare specified name with the ID keyword in the s.file]:name' \
      '-y+[compare specified type with the ID keyword]:type'
    ;;
  what) _arguments '-s[stop after first occurrence]' '*:file:_files';;

  *) _message "unknown sccs command: $service";;
esac
