rlx.commands.attach() {
  if [ -z "${info[database]:-}" ]; then
    console error -- "no database selected";
  elif [ -z "${info[id]:-}" ]; then
    console error -- "no document selected";
  else
    if [ $# -eq 0 ]; then
      console error -- "no attachment command specified";
    else
      local attach_namespace="attach.commands";
      local cmd="${1:-}";
      shift;
      if ! method.exists? "${attach_namespace}.${cmd}"; then
        local file="${cmd}";
        tilde.expand;
        if [ -f "${file}" ]; then
          attach.commands.send "${file}" "$@";
        else
          console error -- "%s does not exist" "${file}";
        fi
      else
        delegate "${attach_namespace}" "${cmd}" "$@";
      fi
    fi
  fi
}


# send an attachment
attach.commands.send() {
  local file="${1:-}";
  local name="${2:-}";
  local mime="${3:-}";
  local id="${info[id]:-}";
  tilde.expand;
  if [ -f "${file}" ]; then
    doc.commands.etag "${id}" false 2>/dev/null;
    if ${flags[success]}; then
      local rev="${info[revision]:-}";
      console info -- "attach %s to %s" "${file}" "${id}";
      rlx.run couchdb.attach \
        "${info[server]:-}" "${info[database]:-}" \
        "${id}" "${rev}" "${file}" "${name}" \
        "${mime}" "${rlx_settings[mime]:-}";
      if ${flags[success]}; then
        console info -- "attached %s" "${file}";
      fi
    else
      console error -- "could not fetch document revision";
    fi
  else
    console error -- "%s does not exist" "${file}";
  fi
}

# attach multiple files
attach.commands.files() {
  local file nested files=( "$@" );
  local targets=();
  for file in "${files[@]}";
  do
      tilde.expand;
      if [[ "${file}" =~ ([^*]+)(/\*{1,2})$ ]]; then
        local directory="${BASH_REMATCH[1]}";
        local glob="${BASH_REMATCH[2]}";
        if [ -d "${directory}" ]; then
          shopt -s nullglob;
          if [[ "${glob}" =~ /\*{2,2}$ ]]; then
            shopt -s globstar;
          fi
          if [ "${rlx_settings[dotglob]}" == true ]; then
            shopt -s dotglob;
          fi
          # shopt -s dotglob
          # GLOBIGNORE
          # shopt -s extglob
          #echo "got glob pattern...$directory ${glob}"
          for nested in "${directory}"$glob
            do
              if [ -f "${nested}" ]; then
                targets+=( "${nested}"  );
              fi
              #echo "got nested $nested"
          done
          shopt -u nullglob globstar failglob dotglob;
          continue;
        else
          console warn -- "glob path %s is not a directory" "${directory}";
        fi
      fi
      if [ -d "${file}" ]; then
        #echo "got file directory...$file"
        console warn -- "%s is a directory, use a glob to include files" \
          "${file}";
      elif [ -f "${file}"  ]; then
        echo "attaching file $file"
        targets+=( "${file}" );
      else
        console warn -- "file %s does not exist" "${file}";
      fi
  done
  attach.multiple;
}

# delete multiple attachments
attach.commands.rm() {
  local name;
  while [ -n "${1:-}" ]; 
    do
      name="${1:-}"; shift;
      attach.rm "${name}";
      if ! ${flags[success]}; then
        break;
      fi
  done
}

# download attachments
attach.commands.get() {
  local context="${rlx_settings[attachments]:-}";
  context="${context%/}";
  if [ ! -d "${context}" ]; then
    console error -- "%s is not a directory" "${context}";
  elif [ ! -w "${context}" ]; then
    console error -- "%s is not writable" "${context}";
  else
    local name;
    while [ -n "${1:-}" ]; 
      do
        name="${1:-}"; shift;
        attach.get "${name}";
        if ! ${flags[success]}; then
          break;
        fi
    done
  fi
}

# download an attachment
attach.get() {
  local name="${1:-}";
  local id="${info[id]:-}";
  doc.commands.etag "${id}" false 2>/dev/null;
  if ${flags[success]}; then
    local rev="${info[revision]:-}";
    rlx.run couchdb.attach.get \
      "${info[server]:-}" "${info[database]:-}" \
      "${id}" "${rev}" "${name}" "${context}/${name}";
    if ${flags[success]}; then
      console info -- "downloaded attachment %s" "${name}";
    fi
  else
    console error -- "could not fetch document revision";
  fi
}

# delete an attachment
attach.rm() {
  local name="${1:-}";
  local id="${info[id]:-}";
  doc.commands.etag "${id}" false 2>/dev/null;
  if ${flags[success]}; then
    local rev="${info[revision]:-}";
    rlx.run couchdb.attach.rm \
      "${info[server]:-}" "${info[database]:-}" \
      "${id}" "${rev}" "${name}";
    if ${flags[success]}; then
      console info -- "deleted attachment %s" "${name}";
    fi
  else
    console error -- "could not fetch document revision";
  fi
}

attach.multiple() {
  send(){
    local submit="${1:-false}";
    for file in "${targets[@]}";
      do
        if $submit; then
          #echo "send file for attching..."
          attach.commands.send "${file}";
        else
          console info -- "attachment %s" "${file}";
        fi
    done
  }
  if [ "${#targets[@]}" -eq 0 ]; then
    console error -- "no files found to attach";
    return 0;
  fi
  send false;
  accepted() {
    send true;
    rlx.prompt;
  }
  console prompt --program \
    "attach %s files? (y/n)" "${#targets[@]}";
  prompt confirm \
    --accepted=accepted \
    --rejected=rlx.rejected \
    --id=attach-files;
}

tilde.expand() {
  # handle tilde exapnsion
  if [[ "${file}" =~ ^(~)(.*)$ ]]; then
    local home=~;
    file="${home}${BASH_REMATCH[2]}";
  fi
}
