#!/bin/sh
#
# Attach to a tmux session, or create it if it doesnt exist

if [ "$1" = '-h' ] || [ "$1" = '--help' ]; then
  cat <<-EOF
  Usage: $0 [FILE] [NAME]
  Attach to an existing tmux session, or bootstrap a new session.

  If no session exists which fits the criteria, this will create a new one and
  load it up obeying the commands contained in the FILE argument passed in. It
  must contain commands which are tmux-command compatible since they will be
  passed to tmux unmodified. If a session exists and a valid configuration FILE is
  passed, it will attach itself to the session and execute the session setup inside.

  It will load the default tmux.conf in the following order:
    - XDG_CONFIG_HOME/tmux/tmux.conf (usually ~/.config/tmux/tmux.conf)
    - ~/.tmux.conf
    - /etc/tmux.conf
  Afterwards, it will apply the contents of the FILE argument passed into the command.

  If no FILE argument is passed it will create an empty session, or attach itself to
  the session specified.

  If no NAME argument is passed it will automatically create a session name from the
  FILE argument passed.

  If creating a new session without passing in a FILE argument, and the current directory
  contains a .tmux.session file, it will automatically use that to set up the session.

  By default, it also looks for valid session files in XDG_CONFIG_HOME/tmux/sessions/
  This path can be changed by setting the TM_SESSION_PATH environment variable.
EOF
  exit 0
fi

# Make tmux obey the XDG specification on startup
if [ -e "$XDG_CONFIG_HOME/tmux/tmux.conf" ]; then
  start="tmux -f $XDG_CONFIG_HOME/tmux/tmux.conf"
else
  start=tmux
fi

_file_exists() {
  if [ -f "$1" ]; then
    true
  else
    false
  fi
}

_not_in_tmux() {
  [ -z "$TMUX" ]
}

_session_exists() {
  if tmux has-session -t "$session_name" >/dev/null 2>&1; then
    true
  else
    false
  fi
}

_create_detached_session() {
  ($start new-session -d -s "$session_name")
}

_load_env_session_file() {
  if [ -f ./.tmux.session ]; then
    xargs -L1 tmux <./.tmux.session
  fi
}

_load_session_file() {
  if [ -f "$session_file" ]; then
    xargs -L1 tmux <"$session_file"
  fi
}

_set_session_file_path() {
  # Prefer local dir if file exists there, fall back to root dir
  if _file_exists "${1}"; then
    session_file="${1}"
  elif _file_exists "${session_dir}${1}"; then
    session_file="${session_dir}${1}"
  fi
}

_set_session_vars() {
  session_dir=${TM_SESSION_DIR:-"$XDG_CONFIG_HOME/tmux/sessions/"}

  # set up session name and config file - if passed in as arguments
  if [ "$#" -eq 2 ]; then
    if ! _file_exists "$1" && ! _file_exists "${session_dir}${1}"; then
      echo >&2 "can not source session file: '${1}' does not exist."
      exit 1
    fi
    _set_session_file_path "$1"
    session_name=${2}
  elif [ "$#" -eq 1 ]; then
    _set_session_file_path "$1"
    if ! _file_exists "$session_file"; then
      session_name=${1}
    fi
  fi

  # set default session name if none was passed
  if [ -z "$session_name" ]; then
    # only if we have a filename should we append it to the session name
    if [ -n "$session_file" ]; then
      fname=/$(basename "$session_file" .session)
    fi
    # default to parent directory name / config file name for the session
    session_name=$(basename "$PWD" | sed 's/[^a-zA-Z0-9\-]//g' | tr . -)"$fname"
  fi
}

_attach_or_create() {
  # first create a new session if one doesn't exist
  if ! _session_exists; then
    _create_detached_session
    # look for .tmux.session file if no file has been explicitly passed in
    # session files always take precedence over environment files when specifically passed in
    if ! _file_exists "$session_file"; then
      _load_env_session_file
    fi
  fi

  _load_session_file

  # then attach or switch to the session
  if _not_in_tmux; then
    $start attach -t "$session_name"
  else
    $start switch-client -t "$session_name"
  fi

  _unset_functions
}

_unset_functions() {
  unset _set_session_vars
  unset _set_session_file_path
  unset _attach_or_create
  unset _load_session_file
  unset _create_detached_session
  unset _session_exists
  unset _not_in_tmux
  unset _file_exists
}

_set_session_vars "$@"
_attach_or_create
exit 0
