# change directory
rlx.commands.cd() {
  local target="${1:-}";
  local id="${2:-}";
  local connect="${3:-true}";
  local server db username;
  if [ -z "${target}" ]; then
    console error -- "missing %s or %s" "url" "alias";
    return 1;
  # got absolute path
  elif [[ "${target}" =~ ${regexp[cdscheme]} ]]; then
    local scheme="${BASH_REMATCH[1]:-}";
    local destination="${BASH_REMATCH[2]:-}";
    local IFS="/";
    local parts=( $destination );
    unset IFS;
    server="${parts[0]:-}";
    db="${parts[1]:-}";
    if [ -z "${server}" ]; then
      console error -- "no server specified";
    else
      server="${scheme}${server}";
      rlx.connect;
    fi
  # alias match
  elif [[ "${target}" =~ ${regexp[alias]} ]]; then
    target="${BASH_REMATCH[2]}";
    local file;
    if alias find "${target}"; then
      alias.load "${file}" || return 1;
      if [ -z "${rlx_alias_server:-}" ]; then
        console error -- "no server found for alias %s" "${target}";
      else
        server="${rlx_alias_server}";
        if [ -n "${rlx_alias_database:-}" ]; then
          db="${rlx_alias_database}";
        fi
        # TODO: handle this when auth is implemented
        if [ -n "${rlx_alias_username:-}" ]; then
          username="${rlx_alias_username}";
        fi
        rlx.connect;
      fi
    else
      return 1;
    fi
  elif [ "${target}" == / ]; then
    info[database]="";
    info[id]="";
    info[revision]="";
  else
    console error -- "could not change directory";
    return 1;
  fi
  rlx.commands.pwd;
}

rlx.connect() {
  # TODO: this gets set even if the connection fails!!
  info[server]="${server}";
  if [ "${connect}" == true ]; then
    console info -- "connect %s" "${server}";
    #rlx.commands.version "${server}" 2>/dev/null;
    rlx.commands.version "${server}";
    #echo "response status is ${http[status]}"
    if [ "${http[status]:-}" != 200 ]; then
      console error -- "could not connect to server %s" \
        "${server}";
    else
      info[server]="${server}";
      if [ -n "${db:-}" ] && [ "${db:-}" != false ]; then
        rlx.commands.db use "${db}" >/dev/null;
        if [ -n "${id}"  ]; then
          doc.commands.use "${id}" >/dev/null;
        fi
      else
        info[database]="";
        info[id]="";
        info[revision]="";
      fi
    fi
  else
    info[server]="${server:-}";
    info[database]="${db:-}";
    info[id]="${id:-}";
    info[revision]="";
  fi
}

rlx.commands.hostname() {
  local server="${info[server]:-}";
  if [ -n "${server}" ] \
    && [[ "${server}" =~ ${regexp[hostname]} ]]; then
      console print --attribute=underline -- "%s" "${BASH_REMATCH[2]}";
  fi
}

# print current working directory
rlx.commands.pwd() {
  local server="${info[server]:-}";
  local db="${info[database]:-}";
  local id="${info[id]:-}";
  local rev="${info[revision]:-}";
  if [ -z "${server}" ]; then
    console error -- "no server selected";
  else
    local str="${server}";
    [[ -n "${db}" ]] && str+="/${db}";
    [[ -n "${id}" ]] && str+="/${id}";
    [[ -n "${rev}" ]] && str+="/${rev}";
    console print --attribute=underline -- "%s" "${str}";
  fi
}

rlx.commands.docs() {
  local server="${1:-${info[server]}}";
  alias.expand || return 1;
  echo "$FUNCNAME";
}

# get the couchdb version
rlx.commands.version() {
  local server="${1:-${info[server]}}";
  alias.expand || return 1;
  rlx.run couchdb.db.info "${server}";
  if ${flags[success]}; then
    rlx.interpreter version;
    local version=$( "$interpreter" < "${files[response]}" );
    if [ -n "${version:-}" ]; then
      info[version]="${version}";
      rlx.version.print;
    fi
  fi
}

rlx.commands.docs() {
  local server="${1:-${info[server]}}";
  alias.expand || return 1;
  local docsurl="${server}/${couchdb[utils]}/${couchdb[docs]}/";
  rlx.run couchdb.docs.head "${server}";
  #echo "docs $server $? $docsurl";
  if ${flags[success]}; then
    rlx.browser.launch "${docsurl}";
  else
    console error -- "no documentation available at %s" "${docsurl}";
  fi
}

rlx.version.print() {
  local version="${1:-${info[version]:-}}";
  local server="${2:-${server:-}}";
  console info -- "couchdb %s (%s)" \
    "${version}" "${server}";
}

# print active tasks
rlx.commands.tasks() {
  local server="${1:-${info[server]}}";
  alias.expand || return 1;
  rlx.run couchdb.tasks "${server}";
  if ${flags[success]}; then
    rlx.json.print;
  fi
}

# print statistics
rlx.commands.stats() {
  local server="${1:-${info[server]}}";
  alias.expand || return 1;
  rlx.run couchdb.stats "${server}";
  if ${flags[success]}; then
    rlx.json.print;
  fi
}

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

# print logs
rlx.commands.log() {
  local bytes="${1:-}";
  rlx.run couchdb.log "${info[server]}" "${bytes}";
  if ${flags[success]}; then
    if [ -f "${files[response]}" ]; then
      cat "${files[response]}";
    else
      console error -- "missing response file %s" \
        "${files[response]}";
    fi
  fi
}

# restart a server
rlx.commands.restart() {
  local server="${1:-${info[server]}}";
  alias.expand || return 1;
  rlx.run couchdb.restart "${server}" > /dev/null 2>&1;
  # NOTE: in this instance success is indicated
  # NOTE: by an empty response from the server
  if [ "${http_exit_code:-}" -eq 52 ]; then
    console info -- "restart %s" "${server}";
  fi
}

# save the last response
rlx.commands.save() {
  local file="${1:-}";
  local input="";
  local sourcefile="${files[response]:-}";
  local prefix="[save]";
  if [ ! -f "${sourcefile}" ]; then
    console error -- "file %s does not exist" "${sourcefile}";
  else
    accepted() {
      copy "${input:-}" true;
      rlx.prompt;
    }
    copy() {
      local input="${1:-}";
      local overwrite="${2:-false}";
      file="${input}";
      # handle tilde exapnsion
      tilde.expand;
      if [[ ! "${input}" =~ / ]] \
        && [ -d "${rlx_settings[downloads]:-}" ]; then
        file="${rlx_settings[downloads]}/${input}";
      fi
      if [ -d "${file}" ]; then
        console error -- "cannot save %s is a directory" "${file}";
      elif [ -f "${file}" ] && ! $overwrite; then
        # prompt to confirm overwrite
        console prompt --prefix="${prefix}" \
          "overwrite %s? (y/n)" "${file}";
        prompt confirm \
          --accepted=accepted \
          --rejected=rlx.rejected \
          --id=overwrite;
      else
        rlx.interpreter;
        local pretty=false;
        if [ "${rlx_settings[savepretty]:-}" == true ]; then
          if rlx.json.enabled "${rlx_settings[lang]:-}" \
            && [ -x "${interpreter}" ]; then
            pretty=true;
          fi
        fi
        local savecmd="cp -f \"${sourcefile}\" \"${file}\" 2>/dev/null";
        if $pretty; then
          savecmd="$interpreter < \"${sourcefile}\" >| \"${file}\"";
        fi
        if ${flags[debug]}; then
          rlx.debug "%s" "${savecmd}";
        fi
        /usr/bin/env bash -c "${savecmd}" \
          || console error -- "could not save to %s" "${file}" \
          && {
            console info -- "saved %s" "${file}";
          };
      fi
    }
    response() {
      input=${1:-};
      # respect quit commands
      if ! array.contains? "${input}" "${quits[@]}"; then
        copy "${input:-}";
      fi
      rlx.prompt;
    }
    if [ -z "${file}" ]; then
      console prompt --prefix="${prefix}" "%s" "${sourcefile}";
      prompt line \
        --response=response \
        --hist-file="${files[history]}" \
        --quit="${quits[*]}" --id=rlx-save;
    else
      copy "${file}";
    fi
  fi
}

server.clear() {
  info[server]="";
  info[database]="";
  info[id]="";
  info[revision]="";
}
