#!/usr/bin/env bash

# See https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -o errexit -o errtrace -o nounset -o pipefail

readonly HELP_HEADING_FORMAT='Enter a new name for workspace "%s"'
readonly HELP_CONTENT_FORMAT='<i>By default only the name is changed, but you can also use colons to change the number or group, In addition, you can use an hyphen ("-") to reset a property. 
Example inputs and what properties they change:</i> %s'
readonly HELP_EXAMPLES='
+-----------+-----------------------------------+
|   Input   |              Changes              |
+-----------+-----------------------------------+
| foo       | name="foo"                        |
| foo:2     | name="foo", number=2              |
| -:2       | name="", number=2                 |
| :2        | number=2                          |
| bar:foo:2 | group="bar", name="foo", number=2 |
| bar::2    | group="bar", number=2             |
+-----------+-----------------------------------+'

readonly HELP_FORMAT='<span alpha="50%%" size="smaller"><b>%s</b>
%s</span>'

ROFI_CMD=(rofi -dmenu -p 'Rename' -theme-str
  'window {width: 60ch;} listview {lines: 0;}')

command_exists() {
  type "$1" &> /dev/null
}

get_tool() {
  filename="$1"
  local dir tool
  dir="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
  tool="${dir}/${filename}"
  command_exists "${tool}" || tool="${filename}"
  printf '%s\n' "${tool}"
}

error() {
  local error normal
  # Red color
  error="$(tput setaf 1 2> /dev/null)" || true
  normal="$(tput sgr0 2> /dev/null)" || true
  printf >&2 '%s\n' "${error}${*}${normal}"
}

rename_workspace() {
  local name_pattern="$1"
  mapfile -d ':' -t fields < <(printf '%s' "${name_pattern}")
  local num_fields=${#fields[@]}
  if ((num_fields == 0)); then
    fields=('')
    num_fields=1
  fi
  local static_name_arg=()
  local local_number_arg=()
  local group_arg=()
  # When there is a single field, i.e. there was no column in the pattern, it
  # means that this is the new static name, even if it's an empty string.
  # In contrast, when there is more than one field, an empty string actually
  # means "do not change".
  if ((num_fields == 1)); then
    static_name_arg=('--name' "${fields[0]}")
  elif ((num_fields == 2)); then
    [[ -n "${fields[0]}" ]] && static_name_arg=('--name' "${fields[0]}")
    [[ -n "${fields[1]}" ]] && local_number_arg=('--number' "${fields[1]}")
  elif ((num_fields == 3)); then
    [[ -n "${fields[0]}" ]] && group_arg=('--group' "${fields[0]}")
    [[ -n "${fields[1]}" ]] && static_name_arg=('--name' "${fields[1]}")
    [[ -n "${fields[2]}" ]] && local_number_arg=('--number' "${fields[2]}")
  else
    error 'Name pattern cannot contain more than 3 colons'
    exit 3
  fi
  # Replace '-' with an empty string.
  [[ "${static_name_arg[1]:-}" == '-' ]] && static_name_arg[1]=''
  [[ "${local_number_arg[1]:-}" == '-' ]] && local_number_arg[1]=''
  [[ "${group_arg[1]:-}" == '-' ]] && group_arg[1]=''
  "${tool}" rename-workspace "${static_name_arg[@]}" "${local_number_arg[@]}" \
    "${group_arg[@]}"

}

main() {
  local tool
  tool="$(get_tool "${I3_WORKSPACE_GROUPS_CLI:-i3-workspace-groups}")"
  mesg=()
  if current_name="$("${tool}" list-workspaces --fields static_name \
    --focused-only)"; then
    local help_heading
    # shellcheck disable=SC2059
    help_heading="$(printf "${HELP_HEADING_FORMAT}" "${current_name}")"
    # shellcheck disable=SC2059
    help_content="$(printf "${HELP_CONTENT_FORMAT}" "${HELP_EXAMPLES}")"
    mesg[1]='-mesg'
    # shellcheck disable=SC2059
    mesg[2]="$(printf "${HELP_FORMAT}" "${help_heading}" "${help_content}")"
  fi
  if ! new_name_pattern="$("${ROFI_CMD[@]}" "${mesg[@]}")"; then
    exit 1
  fi
  rename_workspace "${new_name_pattern}"
}

main "$@"
