# internal shortcut alias
db() {
  rlx.commands.db "$@";
}

rlx.commands.db() {
  if [ $# -eq 0 ]; then
    if [ -z "${info[database]:-}" ]; then
      console error -- "no db selected";
    else
      console info -- "using database %s" "${info[database]}";
    fi
  else
    local db_namespace="db.commands";
    local cmd="${1:-}";
    shift;
    if ! method.exists? "${db_namespace}.${cmd}"; then
      #console error -- "unknown db command %s" "${cmd}";
      db.commands.use "${cmd}" "$@";
    else
      delegate "${db_namespace}" "${cmd}" "$@";
    fi
  fi
}

# sets a database context and executes
# a command and then restores the current
# selected database
db.commands.context() {
  local db="${info[database]:-}";
  local context="${1:-}"; shift;
  info[database]="${context}";
  $@;
  info[database]="${db}";
}

# list databases
db.commands.ls() {
  local server="${1:-${info[server]}}";
  rlx.run couchdb.db.list "${server}";
  if ${flags[success]}; then
    rlx.json.print;
  fi
}

# select a database
db.commands.use() {
  local db="${1:-}";
  if [ -z "${db}" ]; then
    console error -- "no database specified";
  else
    info[database]="${db}";
    info[id]="";
    info[revision]="";
    db head "${db}" false >/dev/null 2>&1;
    if ! ${flags[success]}; then
      if [ "${http[status]:-}" == 404 ]; then
        console warn -- "database %s does not exist" "${db}";
      fi
    fi
    rlx.commands.pwd;
  fi
}

# undocumented
db.commands.head() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.head "${server}" "${db}";
    if ${flags[success]}; then
      return 0;
    fi
  fi
  return 1;
}

# purge a database
# TODO: allow purge information to be added as JSON to the request
db.commands.purge() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.purge "${server}" "${db}";
    if ${flags[success]}; then
      #cat "${files[response]}";
      rlx.json.print;
    fi
  fi
}

# commit to disc
db.commands.commit() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.commit "${server}" "${db}";
    if ${flags[success]}; then
      rlx.json.print;
    fi
  fi
}

# show information for a database
db.commands.info() {
  local db="${1:-${info[database]:-}}";
  local print="${2:-true}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.info "${server}" "${db}";
    if ${flags[success]} && $print; then
      rlx.json.print;
    fi
  fi
}

# compact a database
db.commands.compact() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.compact "${server}" "${db}";
    if ${flags[success]}; then
      console info -- "compaction started on %s" "${db}";
    fi
  fi
}

# get or set the revslimit for a database
db.commands.revslimit() {
  local db="${info[database]:-}";
  local limit="${1:-}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.revslimit "${server}" "${db}" "${limit}";
    if ${flags[success]}; then
      if [ ! -f "${files[response]}" ]; then
        console error -- "could not retrieve revslimit for %s" "${db}";
        console error -- "missing response document %s" "${files[response]}";
      else
        local revslimit;
        if [ -z "${limit}" ]; then
          revslimit="$( cat "${files[response]}" )";
        else
          # NOTE: re-run the command so that
          # NOTE: the actual modified revslimit
          # NOTE: is displayed when setting the revslimit
          db.commands.revslimit;
          return 0;
        fi
        console info -- "revslimit %s" "${revslimit}";
      fi
    fi
  fi
}

# perform view cleanup on a database
db.commands.cleanup() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.cleanup "${server}" "${db}";
    if ${flags[success]}; then
      console info -- "view cleanup started on %s" "${db}";
    fi
  fi
}

# get changes for a database
db.commands.changes() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database selected";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.changes "${server}" "${db}";
    if ${flags[success]}; then
      rlx.json.print;
    fi
  fi
}

# add a database
db.commands.add() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database specified";
  else
    local server="${info[server]}";
    rlx.run couchdb.db.add "${server}" "${db}";
    if ${flags[success]}; then
      console info -- "database %s created" "${db}";
      if [ "${db}" != "${info[database]:-}" ]; then
        db.commands.use "${db}";
      fi
    fi
  fi
}

# delete a database
db.commands.rm() {
  local db="${1:-${info[database]:-}}";
  if [ -z "${db}" ]; then
    console error -- "no database specified";
  else
    local server="${info[server]}";
    accepted() {
      rlx.run couchdb.db.rm "${server}" "${db}";
      if ${flags[success]}; then
        console info -- "database %s deleted" "${db}";
        if [ "${info[database]:-}" == "${db}" ]; then
          info[database]="";
        fi
      fi
      rlx.prompt;
    }
    console prompt --program \
      "delete database %s? (y/n)" "${db}";
    prompt confirm \
      --accepted=accepted \
      --rejected=rlx.rejected \
      --id=delete;
  fi
}
