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

rlx.commands.previous() {
  page previous "$@";
}

rlx.commands.next() {
  page next "$@";
}

rlx.commands.reverse() {
  page reverse "$@";
}

rlx.commands.invert() {
  page invert "$@";
}

# main
rlx.commands.page() {
  if [ $# -eq 0 ]; then
    console error -- "no page command specified";
  else
    local keys=(
      page_next page_next_docid page_next_startkey
      page_previous_docid page_previous_startkey
      page_total page_offset page_length page_limit
    );
    local namespace="page.commands";
    local cmd="${1:-}"; shift;
    if ! method.exists? "${namespace}.${cmd}"; then
      console error -- "unknown page command %s" "${cmd}";
    else
      delegate "${namespace}" "${cmd}" "$@";
    fi
  fi
}

page.commands.next() {
  local tmpfile="${PAGE_TMP_FILE:-}";
  if [ -z "${tmpfile}" ]; then
    console warn -- "no page information";
  else
    #console info -- "paginate with $tmpfile";
    . "${tmpfile}" \
      || {
        console error -- "could not load %s" "${tmpfile}";
        return 1;
      }
    if [ "${page_next}" == false ]; then
      console warn -- "no next page";
    else
      local pagecmd="${PAGE_COMMAND:-}";
      export PAGE_STARTKEY="${page_next_startkey}";
      export PAGE_STARTKEY_DOCID="${page_next_docid}";
      page_previous_keys+=("${page_previous_startkey}");
      page_previous_docids+=("${page_previous_docid}");
      $pagecmd;
    fi
  fi
}

page.commands.previous() {
  local tmpfile="${PAGE_TMP_FILE:-}";
  if [ -z "${tmpfile}" ]; then
    console warn -- "no page information";
  else
    local length=${#page_previous_keys[@]};
    if [ ${length} -eq 0 ]; then
      console warn -- "no previous page";
    else
      local index=$((length-1));
      local pagecmd="${PAGE_COMMAND:-}";
      local startkey="${page_previous_keys[$index]}";
      local docid="${page_previous_docids[$index]}";
      export PAGE_STARTKEY="${startkey}";
      export PAGE_STARTKEY_DOCID="${docid}";
      unset page_previous_keys[$index] page_previous_docids[$index];
      $pagecmd;
    fi
  fi
}

page.commands.reverse() {
  local tmpfile="${PAGE_TMP_FILE:-}";
  if [ -z "${tmpfile}" ]; then
    console warn -- "no page information";
  else
    local pagecmd="${PAGE_COMMAND:-}";
    local descending="${rlx_settings[descending]:-false}";
    if [ "${descending}" == false ]; then
      descending=true;
    else
      descending=false;
    fi
    local print=false;
    settings set descending "${descending}";
    paginate.clean;
    $pagecmd;
  fi
}

page.commands.invert() {
  local tmpfile="${PAGE_TMP_FILE:-}";
  if [ -z "${tmpfile}" ]; then
    console warn -- "no page information";
  else
    local pagecmd="${PAGE_COMMAND:-}";
    local interpreter;
    rlx.interpreter invert;
    local json=$( < "${files[input]}" );
    "${interpreter}" <<< "${json}" >| "${files[input]}"; 
    rlx.debug "%s < %s >| %s" "$interpreter" "${files[input]}" "${files[input]}";
    rlx.json.print "${files[input]}";
  fi
}

# print page information
page.commands.info() {
  if [ -z "${PAGE_TMP_FILE:-}" ] \
    || [ ! -f "${PAGE_TMP_FILE:-}" ]; then
    console error -- "no page information available";
    return 1;
  fi
  console print -- "page_file=%s" "${PAGE_TMP_FILE:-}";
  console print -- "page_command=%s" "${PAGE_COMMAND:-}";
  . "${PAGE_TMP_FILE}" \
    || {
      console error -- "failed to load %s" "${PAGE_TMP_FILE}";
      return 1;
    }
  local k v;
  for k in "${keys[@]}"
    do
      variable.get "${k}" "v";
      console print -- "${k}=%s" "${v}";
  done
  local index="${#page_previous_keys[@]}";
  local current=$((index+1));
  console print -- "page_keys_length=%s" "${#page_previous_keys[@]}";
  console print -- "page_docids_length=%s" "${#page_previous_docids[@]}";
  console print -- "page_index=%s" "${index}";
  console print -- "page_current=%s" "${current}";
}

# clean all pagination information
page.commands.clean() {
  paginate.clean;
}

## PRIVATE

rlx.json.paginate() {
  local file="${1:-${files[response]:-}}";
  local pagecmd="${2:-}";
  local tmpname="paginate.sh";
  export PAGE_LIMIT="${limit:-${rlx_settings[limit]:-10}}";
  export PAGE_TMP_NAME="${tmpname}";
  export PAGE_COMMAND="$pagecmd";
  local server="${info[server]:-}";
  local tmpfile="${directories[tmp]}/${tmpname}";
  export PAGE_TMP_FILE="${tmpfile}";
  rlx.debug "page file %s" "${tmpfile}";
  rlx.interpreter paginate;
  rlx.debug "%s < %s >| %s" "$interpreter" "$file" "${files[input]}";
  "$interpreter" < "${file}" >| "${files[input]}";
  #cat "${file}";
  rlx.json.print "${files[input]}";
  if [ ! -f "${tmpfile}" ]; then
    console error -- "no pagination document %s" "${tmpfile}";     
  fi
}

paginate.clean() {
  local tmpfile="${PAGE_TMP_FILE:-}";
  if [ -f "${tmpfile}" ]; then
    rm "${tmpfile}";
    rlx.debug "clean pagination %s" "${tmpfile}";
  fi
  unset -v ${!page_*} ${!PAGE_*};
  paginate.reset;
}

paginate.reset() {
  # pagination previous keys
  declare -ag page_previous_keys;
  declare -ag page_previous_docids;
  declare -Ag page_data;
  page_data[current]=0;
}
