#!/bin/sh

SCRIPT_NAME=$0

#################
# Configuration #
#################

# List of all env variable
declare -A DATABASE_VAR_DESCRIPTION
DATABASE_VAR_DESCRIPTION["DATABASE_HOST"]="Set database host"
DATABASE_VAR_DESCRIPTION["DATABASE_PORT"]="Set database port"
DATABASE_VAR_DESCRIPTION["DATABASE_USER"]="Set database user"
DATABASE_VAR_DESCRIPTION["DATABASE_PASSWORD"]="Set database password, never share your .env file, your password is stored in clear"
DATABASE_VAR_DESCRIPTION["DATABASE_NAME"]="Set database name"
DATABASE_VARS="${!DATABASE_VAR_DESCRIPTION[@]}"

declare -A CONFIG_CATEGORIES_DESCRIPTION
CONFIG_CATEGORIES_DESCRIPTION["DATABASE"]="Set database related config vars"
CONFIG_CATEGORIES=(DATABASE)

CONFIG_VARS="$DATABASE_VARS"

################
# USEFULL VARS #
################

# Usefull vars for using dialog, kdialog and xdialog
: ${DIALOG_OK=0}
: ${DIALOG_CANCEL=1}
: ${DIALOG_HELP=2}
: ${DIALOG_EXTRA=3}
: ${DIALOG_ITEM_HELP=4}
: ${DIALOG_ESC=255}
# Colors
: ${BLACK='\033[0:30m'}
: ${RED='\033[0;31m'}
: ${GREEN='\033[0;32m'}
: ${ORANGE='\033[0;33m'}
: ${BLUE='\033[0;34m'}
: ${PURPLE='\033[0;35m'}
: ${CYAN='\033[0;36m'}
: ${LIGHT_GRAY='\033[0;37m'}
: ${DARK_GRAY='\033[1;30m'}
: ${LIGHT_RED='\033[1;31m'}
: ${LIGHT_GREEN='\033[1;32m'}
: ${YELLOW='\033[1;33m'}
: ${LIGHT_BLUE='\033[1;34m'}
: ${LIGHT_PURPLE='\033[1;35m'}
: ${LIGHT_CYAN='\033[1;36m'}
: ${WHITE='\033[1;37m'}
: ${NC='\033[0m'}

##########################
# Rewrite beautiful echo #
##########################

einfo () {
# einfo "comment"
    echo -e " ${GREEN}*${NC} ${@:1}${NC}"
}
ewarn () {
# ewarn "comment"
    echo -e " ${YELLOW}*${NC} ${@:1}${NC}"
}
eerror () {
# eerror "comment"
    echo -e " ${RED}*${LIGHT_RED} ${@:1}${NC}"
}
die () {
# die exit_code "comment"
    echo
    eerror $2
    exit $1
}
eend () {
# eend exit_status "comment"
    einfo $2
    exit $1
}
show_help () {
# show_help
    echo "Usage : PDMI-configure [OPTIONS...]"
    echo
    echo " -h, --help   Print this help menu"
    echo " --xdialog    Use xdialog instead of dialog"
}

####################
# Useful functions #
####################



###################
# Parse arguments #
###################

SHORT=h:
LONG=xdialog,help,easter-egg:

OPTS=$(getopt --options ${SHORT} --long ${LONG} --name "$0" -- "$@")

# Problem when parsing args
if [[ $? != 0 ]] ; then echo "Failed to parse options...exiting." >&2 ; exit 1 ; fi

eval set -- "${OPTS}"

DIALOG=dialog

while true ; do
  case "$1" in
    --xdialog )
      which Xdialog && : || die 1 "Xdialog not found"
      DIALOG=Xdialog
      shift
      ;;
    --easter-egg)
      die 0 "Suwako, je t'ai vu décortiquer le fichier"
      ;;
    -h | --help )
      show_help
      end
      shift
      ;;
    -- )
      shift
      break
      ;;
    *)
      echo "Internal error!"
      exit 1
      ;;
  esac
done

set_env_var () {
load_config
  exec 3>&1
  local value=$(${DIALOG} \
    --backtitle "Configuration" \
    --title $1 \
    --inputbox "Veuillez insérez la nouvelle valeur de la variable ${1}:" \
    0 0 \
    ${!1} \
    2>&1 1>&3)
  local exit_status=$?
  exec 3>&-
  export ${1}=$value
  save_config
}

set_env_vars_cat () {
  clear
  CATEGORY=$1
  CATEGORY_VARS_NAME=${1}_VARS
  CAT=${!CATEGORY_VARS_NAME}
  CATEGORY_LIST=($CAT)
  local OPTIONS=""
  local COUNT=${#CATEGORY_LIST[@]}
  for I in `seq 1 ${COUNT}`;
  do
    OPTIONS="$OPTIONS "${I}" "${CATEGORY_LIST[$(($I-1))]}""
  done
  echo $OPTIONS
  exec 3>&1
  selection=$(${DIALOG} \
    --backtitle "PDMI - Configuration" \
    --title "Set $CATEGORY vars" \
    --help-button \
    --menu "Choose an option" \
    -1 -1 0 \
    ${OPTIONS} \
    2>&1 1>&3)
  exit_status=$?
  exec 3>&-
  case ${exit_status} in
    ${DIALOG_CANCEL})
      return
      ;;
    ${DIALOG_HELP})
      ;;
    ${DIALOG_ESC})
      return
      ;;
  esac
  set_env_var ${CATEGORY_LIST[$(($selection-1))]}
}

set_env_vars () {
  local OPTIONS=""
  local COUNT=`echo "$CONFIG_CATEGORIES" | wc -w`
  for I in `seq 1 ${COUNT}`;
  do
    OPTIONS="$OPTIONS "${I}" "${CONFIG_CATEGORIES[$(($I-1))]}""
  done
  exec 3>&1
  selection=$(${DIALOG} \
     --backtitle "PDMI - Configuration" \
     --title "Set configuration vars" \
     --help-button \
     --menu "Choose an option" \
     -1 -1 0 \
     ${OPTIONS} \
     2>&1 1>&3)
  exit_status=$?
  exec 3>&-
  case ${exit_status} in
    ${DIALOG_CANCEL})
      return
      ;;
    ${DIALOG_HELP})
      local HELP=""
      for NAME in ${!CONFIG_CATEGORIES_DESCRIPTION[@]}; do
        HELP="$HELP\n${NAME} - ${CONFIG_CATEGORIES_DESCRIPTION[${NAME}]}"
      done
      echo ${HELP}
      ${DIALOG} \
        --backtitle "PDMI - Set configuration vars" \
        --title "Set configuration vars - Help" \
        --msgbox "$HELP" \
        -1 -1
      ;;
    ${DIALOG_ESC})
      return
      ;;
  esac
  set_env_vars_cat $CONFIG_CATEGORIES
}

load_config () {
  export $(cat .env | xargs)
}

save_config () {
  rm .env
  for VAR in ${CONFIG_VARS}
  do
    if [[ -z ${!VAR} ]]; then
      export ${VAR}=${VAR}
    fi
    echo ${VAR}=${!VAR} >> .env
  done
}

bdd_config () {
  exec 3>&1
  local selection=$(${DIALOG} \
    --backtitle "Base de donnée" \
    --menu "Que souhaitez vous faire?" \
    0 0 0 \
    "1" "manage db init" \
    "2" "manage db migrate" \
    "3" "manage db upgrade" \
    2>&1 1>&3)
  local exit_status=$?
  exec 3>&-
  source .env
  case ${selection} in
    1)
      pipenv run python manage.py db init;;
    2)
      pipenv run python manage.py db migrate;;
    3)
      pipenv run python manage.py db upgrade;;
  esac
}

add_super_admin () {
  exec 3>&1
  local utilisateur=$(${DIALOG} \
    --backtitle "Utilitaires" \
    --title "Administrateurs" \
    --inputbox "Entrez le mail de l'utilisateur que vous voulez passer en superadministrateur" \
    0 0 \
    "" \
    2>&1 1>&3)
  local exit_status=$?
  exec 3>&-
  source .env
  pipenv run python manage.py set_superadmin -m "${utilisateur}"
  exit
}

utilitaires () {
  exec 3>&1
  selection=$(${DIALOG} \
    --backtitle "Utilitaires" \
    --menu "Que voulez vous faire?" \
    0 0 0 \
    "1" "Ajouter un superadministrateur" \
    "2" "Installation de pipenv" \
    2>&1 1>&3)
  exit_status=$?
  exec 3>&-
  case ${selection} in
    1)
      add_super_admin;;
    2)
      pipenv install;;
  esac
}

check_config_file () {
  clear
  export $(cat .env | xargs)
  rm .env
  echo ${CONFIG_VARS}
  for VAR in ${CONFIG_VARS}
  do
    echo ${VAR}=${!VAR}
    if [[ -z ${!VAR} ]]; then
      export ${VAR}=${VAR}
    fi
    echo ${VAR}=${!VAR} >> .env
  done
}

initialisation () {
:
}

start () {
  pipenv run gunicorn wsgy -b 0.0.0.0:8000
}

configuration () {
  exec 3>&1
  selection=$(${DIALOG} \
     --backtitle "PDMI - Configuration" \
     --title "Configuration" \
     --help-button \
     --menu "Choose an option" \
     -1 -1 0 \
     "1" "Check config file" \
     "2" "Set configuration" \
     "-" "" \
     "3" "Exit" \
     2>&1 1>&3)
  exit_status=$?
  exec 3>&-
  case ${exit_status} in
    ${DIALOG_OK})
      ;;
    ${DIALOG_CANCEL})
      return
      ;;
    ${DIALOG_HELP})
      ${DIALOG} \
        --backtitle "PDMI - Configuration" \
        --title "Configuration - Help" \
        --msgbox "Check config file - Check config file integrity
Set configuration - Set configuration" \
        -1 -1
      ;;
    ${DIALOG_ESC})
      return
      ;;
  esac
  case ${selection} in
    1)
      check_config_file
      ;;
    2)
      set_env_vars
      ;;
    3)
      break
      ;;
  esac
}

# Main loop
while true; do
  exec 3>&1
  selection=$(${DIALOG} \
     --backtitle "PDMI - Configuration" \
     --title "Configuration" \
     --help-button \
     --menu "Choose an option" \
     -1 -1 0 \
     "1" "Initialisation" \
     "2" "Configuration" \
     "3" "Start" \
     "-" "-" \
     "4" "Quit" \
     2>&1 1>&3)
  exit_status=$?
  exec 3>&-
  case ${exit_status} in
    ${DIALOG_OK})
      ;;
    ${DIALOG_CANCEL})
      eend 0 "End."
      ;;
    ${DIALOG_HELP})
      ${DIALOG} \
        --backtitle "PDMI - Configuration" \
        --title "Configuration - Help" \
        --msgbox "Initialisation - \n\nConfiguration - Configure usefull parameters, such as port, database uri, ..." \
        -1 -1
      ;;
    ${DIALOG_ESC})
      eend 0 "End."
      ;;
  esac
  case ${selection} in
    1)
      initialisation;;
    2)
      configuration;;
    3)
      start;;
    4)
      exit;;
  esac
done
