#!/bin/bash

############ Script config #############
## GUI mode
#
# Console based:
# dialog - ncurses, runs fine on WSL
# none - works everywhere
#
# GUI based:
# yad, gtkdialog, kdialog, Xdialog - GNU/Linux only
# zenity - Windows port available, doesn't work very well because Microsoft is a little bitch and
#   argument passing between Linux and Windows doesn't work well.
export supermode="zenity"

## Emojis - auto, yes, no
export emojis="auto"
########### /Script config #############

function is_wsl {
  grep -q Microsoft /proc/version
  return $?
}

if is_wsl; then
  alias zenity=zenity.exe
fi

# Determine script location
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"

export supertitle="shcrt"

export SHELL_LIBRARY_PATH="$SHELL_LIBRARY_PATH:$DIR/easybashgui/lib"
export PATH="$PATH:$DIR/easybashgui/src"
source easybashgui
function wsl_win_var {
  cmd.exe /C "echo $1" | tr -d '\r'
}

function win_path_to_wsl {
  if [[ "$1" != "" ]]; then
    echo "$1" | sed -e 's|\\|/|g' -e 's|\(.*\):|/mnt/\L\1|'
  else
    cat - | sed -e 's|\\|/|g' -e 's|\(.*\):|/mnt/\L\1|'
  fi
}

function copy_to_clipboard {
  if is_wsl; then
    cat - | clip.exe
  elif [[ "$WAYLAND_DISPLAY" != "" ]] && which wl-copy > /dev/null; then
    cat - | wl-copy
  elif which xclip > /dev/null; then
    cat - | xclip -selection clipboard
  else
    return 1
  fi
}

# Escape bash variables
function no_dollars {
  sed 's/\$/\\$/g'
}

function scrt_session_path {
  if is_wsl; then
    appdata="$(wsl_win_var '%APPDATA%' | win_path_to_wsl)"
    echo "$appdata/VanDyke/Config/Sessions"
  else
    echo "$HOME/.vandyke/SecureCRT/Config/Sessions"
  fi
}

if [[ "$emojis" == "no" ]] || ([[ "$emojis" != "yes" ]] && is_wsl); then
  dir_char="+"
  file_char=" "
  search_entry="> Search"
  up_entry=".. Back"
  exit_search_entry="X  Exit search"
  query_question="Enter search query: "
  now_at_entry="Now at: "
else
  dir_char="📁"
  file_char="🔗"
  search_entry="🔍 Search"
  up_entry="â†Šī¸ .. Back"
  exit_search_entry="❌ Exit search"
  query_question="🔍 Enter search query: "
  now_at_entry="📍 Now at: "
fi

session_path="$(scrt_session_path)"
current_path="."

function scrt_cd {
  newdir="$session_path/$current_path/$1"
  if [ ! -d "$newdir" ]; then
    return 1
  fi
  current_path="$(realpath --no-symlinks --relative-to "$session_path" "$newdir")"
}

function scrt_pwd {
  echo "$session_path/$current_path"
}

function find_dirs_or_symlinks {
  while read -r name; do
    [ -d "$name" ] && echo "$name";
  done < <(find $@)
}

function find_files_or_symlinks {
  while read -r name; do
    [ -f "$name" ] && echo "$name";
  done < <(find $@)
}

function scrt_ls {
  cwd="$(pwd)"
  cd "$(scrt_pwd)"

  find_dirs_or_symlinks -maxdepth 1 -mindepth 1 | sort | sed "s|./||" | while read dir; do
    echo "$dir_char $dir\\$dir"
  done

  find_files_or_symlinks -maxdepth 1 -mindepth 1 | grep '.ini$' | grep -v 'Default.ini' | grep -v '__FolderData__.ini' | sort | sed 's|./||' | while read file; do
    proto="$(cat "$file" | grep 'S:"Protocol Name"' | cut -d '=' -f 2 | tr -d '\r')"
    echo "$file_char $(echo "$file" | sed 's/.ini$//') ($proto)\\$file"
  done

  cd "$cwd"
}

function scrt_find {
  query="$1"
  (
    find "$session_path/$current_path" -type d -iname '*'"$query"'*'
    find "$session_path/$current_path" -type f -iname '*'"$query"'*.ini$' | grep -v "__FolderData__.ini" | grep -v "Default.ini"
  )| while read result; do
    if basename "$result" | grep -qi "$query"; then
      realpath --relative-to "$session_path/$current_path" "$result"
    fi
  done
}

function scrt_search {
  input 1 "$query_question"
  query="$(cat "${dir_tmp}/${file_tmp}")"
  query="${query#"$query_question"}"

  if [[ "$query" == "" ]]; then
    return 1
  fi

  results="$(scrt_find "$query")"

  if [[ "$results" == "" ]]; then
    alert_message "No results"
    return 1;
  fi

  IFSBAK="$IFS"
  IFS=$'\n'
  menu "$exit_search_entry" $results
  IFS="$IFSBAK"

  menu_choice="$(0< "${dir_tmp}/${file_tmp}" )"
  if [[ "$menu_choice" == "$exit_search_entry" ]]; then
    return 1
  else
    choice_path="$(scrt_pwd)/$menu_choice"
    if [ -d "$choice_path" ]; then
      scrt_cd "$menu_choice"
      return 1
    else
      scrt_session "$menu_choice"
    fi
  fi
}

function scrt_menu {
  listing="$(scrt_ls)"
  menu_listing="$(echo "$listing" | cut -d "\\" -f 1 | no_dollars)"

  now_at="$(echo "$current_path" | sed -e 's|^[.]|/|' -e 's|//|/|' | no_dollars)"

  IFSBAK="$IFS"
  IFS=$'\n'
  if [[ "$current_path" != "" ]] && [[ "$current_path" != "." ]]; then
    menu "$now_at_entry $now_at" "$search_entry" "$up_entry" "$menu_listing"
  else
    menu "$now_at_entry $now_at" "$search_entry" "$menu_listing"
  fi
  IFS="$IFSBAK"

  menu_choice="$(0< "${dir_tmp}/${file_tmp}" )"
  choice="$(echo "$listing" | grep "$menu_choice" | cut -d "\\" -f 2)"
  choice_path="$(scrt_pwd)/$choice"

  #echo "HERE MENU"
  #echo "'$menu_choice' '$up_entry' '$search_entry'"
  #echo "'$choice'"
  #echo "'$choice_path'"

  if [[ "$menu_choice" == "" ]] || [[ "$menu_choice" == "$up_entry" ]]; then
    scrt_cd ..
    if [[ "$current_path" == "" ]] || [[ "$current_path" == ".." ]]; then
      return
    else
      scrt_menu
    fi
  elif [[ "$menu_choice" == "$search_entry" ]]; then
    if scrt_search; then
      return
    else
      scrt_menu
    fi
  elif [[ "$menu_choice" == "$now_at_entry"* ]]; then
    scrt_menu
  elif [ -d "$choice_path" ]; then
    scrt_cd "$choice"
    scrt_menu
  elif [ -f "$choice_path" ]; then
    scrt_session "$choice_path"
  else
    alert_message "Could not find selected item \"$menu_choice\""
  fi
}

function scrt_has_password {
  cat "$1" | grep -q '"Password"'
  return $?
}

function scrt_get_cleartext_pwd {
  session="$1"
  encrypted="$(cat "$session" | grep '"Password V2"' | cut -d '=' -f 2 | cut -c 1-3 --complement | tr -d '\r')"
  if [[ "$encrypted" == "" ]]; then
    encrypted="$(cat "$session" | grep '"Password"' | cut -d '=' -f 2 | cut -c 1 --complement | tr -d '\r')"
    "$DIR/SecureCRTCipher.py" dec "$encrypted"
  else
    "$DIR/SecureCRTCipher.py" dec -v2 "$encrypted"
  fi
}

function scrt_session {
  if [[ "$mode" == "dialog" ]] || [[ "$supermode" == "dialog" ]]; then
    clear
  fi

  session="$1"
  echo
  echo "Session file:"
  echo "$session"
  echo
  echo "Commands:"
  "$DIR/crt2foss.py" "$session_path/../" "$session"

  if scrt_has_password "$session"; then
    echo
    if scrt_get_cleartext_pwd "$session" | tr -d '\r\n' | copy_to_clipboard; then
      echo "Password copied to clipboard."
    else
      echo "Unable to copy password to clipboard."
      read -p "Do you want me to print it to the console? [yN] " yn
      case $yn in
        [Yy]*) scrt_get_cleartext_pwd "$session";;
      esac
    fi
  fi    
}

function main {
  if [ ! -d "$session_path" ]; then
    alert_message "SecureCRT session path not found.\nLooked for it at:\n$session_path"
    return 1
  fi
  scrt_menu
}

# Run if not sourced
BASH_SOURCE=".$0"
test ".$0" != ".$BASH_SOURCE" || main $@