#!/bin/bash

# Reset
Color_Off='\033[0m'       # Text Reset

# Regular Colors
Black='\033[0;30m'        # Black
Red='\033[0;31m'          # Red
Green='\033[0;32m'        # Green
Yellow='\033[0;33m'       # Yellow
Blue='\033[0;34m'         # Blue
Purple='\033[0;35m'       # Purple
Cyan='\033[0;36m'         # Cyan
White='\033[0;37m'        # White

# Underline
UBlack='\033[4;30m'       # Black
URed='\033[4;31m'         # Red
UGreen='\033[4;32m'       # Green
UYellow='\033[4;33m'      # Yellow
UBlue='\033[4;34m'        # Blue
UPurple='\033[4;35m'      # Purple
UCyan='\033[4;36m'        # Cyan
UWhite='\033[4;37m'       # White

# Background
On_Black='\033[40m'       # Black
On_Red='\033[41m'         # Red
On_Green='\033[42m'       # Green
On_Yellow='\033[43m'      # Yellow
On_Blue='\033[44m'        # Blue
On_Purple='\033[45m'      # Purple
On_Cyan='\033[46m'        # Cyan
On_White='\033[47m'       # White

#show banner
clear
echo -e "${Red}"
echo ""
echo "  ███████ ██████  ████████ ███████ ██   ██  █████  ██████  ";
sleep 0.1
echo "  ██      ██   ██    ██    ██      ██  ██  ██   ██ ██   ██ ";
sleep 0.1
echo "  █████   ██████     ██    █████   █████   ███████ ██████  ";
sleep 0.1
echo "  ██      ██   ██    ██    ██      ██  ██  ██   ██ ██   ██ ";
sleep 0.1
echo "  ███████ ██████     ██    ███████ ██   ██ ██   ██ ██   ██ ";
echo ""
echo -e "${Color_Off}"

script_path="/root/voip_server_initial_setup/"

# Set the path to the voip_server application
voip_server_path="/root/voip_managment_server/"

# Define an array of symbols to use for the loading indicator
  spinner=( 'Loading /' 'Loading -' 'Loading \' 'Loading |' )

# Define a function to display the loading indicator
spin() {
  

  # Run an infinite loop
  while true; do
    # Display each symbol of the loading indicator in order
    for i in "${spinner[@]}"; do
      # Clear the previous line and display the new symbol
      echo -ne "\r$i"
      # Wait for 0.1 seconds
      sleep 0.1
    done
  done
}

loding_start(){

    spinner=( "$1 -" "$1 /" "$1 |" "$1 \ " )
    spin &
    # Save the process ID of the loading indicator
    SPIN_PID=$!
}

loding_stop(){
    # Clear the line
    echo -ne "\r\033[K"
    kill -s SIGTERM $SPIN_PID
    sleep 0.1 
    # Unset the SPIN_PID variable
    unset SPIN_PID

}

function update()
{
 printf  "${Cyan}update centos\n${Color_Off}"
 yum update -y
}

function install_packages()
{
       cd packages
       loding_start "install packages" 
       sudo rpm -ivh --force  *.rpm > /dev/null 2>&1
       loding_stop 2>/dev/null
       cd ../

       printf  "${Green}packages installed\n${Color_Off}"
}

function install_node()
{
 version=$(node -v 2>/dev/null)
 if [ -z "$version" -o "$version" != "v14.18.1" ]; then
       loding_start "install node js" 

       tar xzf node-v14.18.1-linux-x64.tar.gz > /dev/null 2>&1
       cd node-v14.18.1-linux-x64 
       for dir in bin include lib share; do cp -par ${dir}/* /usr/local/${dir}/; done > /dev/null 2>&1
       cd ../

       loding_stop 2>/dev/null

       printf  "${Green}node.js 14.18.1 installed\n${Color_Off}"
 else
       printf  "${UGreen}node.js 14.18.1 already installed\n${Color_Off}"
 fi   
}

function install_pm2()
{
 version=$(pm2 --version 2>/dev/null)
 if [ "$version" != "5.1.2" ]; then
        loding_start "install pm2"

        tar -xvf pm2-5.1.2.tgz > /dev/null 2>&1
        cd pm2
        npm install -g > /dev/null 2>&1
        cd ../

        loding_stop 2>/dev/null

        printf  "${Green}pm2 5.1.2 installed\n${Color_Off}"
 else
  printf  "${UGreen}pm2 5.1.2 already installed\n${Color_Off}"
 fi
}


function install_git_v2()
{
 version=$(git --version 2>/dev/null)
 
 if [ "$version" != "git version 2.9.5" ]; then
  loding_start "install git"

  tar -xvf git-2.9.5.tar.gz > /dev/null 2>&1
  cd git-2.9.5
  make configure > /dev/null 2>&1
  sudo ./configure --prefix=/usr > /dev/null 2>&1
  sudo make > /dev/null 2>&1
  sudo make install > /dev/null 2>&1

  config_git
  cd ../

  loding_stop 2>/dev/null

  printf  "${Green}git 2.9.5 installed\n${Color_Off}"
 else
  printf  "${UGreen}git 2.9.5 already installed\n${Color_Off}"
 fi
}

function config_git(){
  git config --global user.name "Mohamad Rezaie"
  git config --global user.email m.rezaie.aval@gmail.com
}

function create_mysql_db()
{
 password='69603AaB@'
 result=$(mysql --user=root --password=$password  -Bse "CREATE DATABASE ebtekar; GRANT ALL PRIVILEGES ON *.* To 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;"  2>&1 )
 
 while [[ "$result" == "ERROR 1045"* ]]
 do
  printf  "${Red}password is not correct\n${Color_Off}"
  read -s -p "Please enter your mysql password: " password
  result=$(mysql --user=root --password=$password  -Bse "create database ebtekar; GRANT ALL PRIVILEGES ON *.* To 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;"  2>&1 )
  printf  "\n"
 done

 if [[ "$result" == *"ERROR 1007"* ]]; then
        printf  "${UGreen}ebtekar database already created\n${Color_Off}"
 else
    printf  "${UGreen}Databse Created\n${Color_Off}"
 fi

 if [ $(mysql --user=root --password=$password -e "use ebtekar; show tables like 'usermap';" | wc -l) -eq 0 ]
 then
    echo "restore database"
    result=$(mysql --user=root --password=$password ebtekar < ebtekar.sql)2>&1
    echo = $result
    if [[ "$result" == *"ERROR 1007"* ]]; then
        printf  "${UGreen}restore failed\n${Color_Off}"
        return 1
    else
      printf  "${UGreen}Databse restored\n${Color_Off}"
    fi
 fi
}

function setup_voip_server()
{
  if [ ! -d "$voip_server_path" ]; then
    echo "The project is not cloned. Please choose one of the following options:"
    echo "1. Clone the project from http://192.168.2.221"
    echo "2. Clone the project from http://efspco.ir"
    echo "3. Clone the project from another URL"
    echo "4. Exit"
    read -p "Enter your choice: " choice
    case $choice in
        1)
            git clone http://192.168.2.221:3000/rezaie/voip_managment_server.git $voip_server_path
            tar xf $voip_server_path/node_modules.tar.gz -C $voip_server_path
            ;;
        2)
            git clone http://efspco.ir:9696/rezaie/voip_managment_server.git $voip_server_path
            tar xf $voip_server_path/node_modules.tar.gz -C $voip_server_path
            ;;
        3)
            read -p "Enter the URL of the project: " url
            git clone $url $voip_server_path
            tar xf $voip_server_path/node_modules.tar.gz -C $voip_server_path
            ;;
        4)
            exit 0
            ;;
        *)
            echo "Invalid choice"
            exit 1
            ;;
    esac
  else
      PS3="Please choose one of the following options:"
      options=("Pull the latest changes" "Edit env" "voip server state" "copy resources" "update scripts"  "extract node_modules" "pack node_modules"   "Delete the project" "Exit")
      select opt in "${options[@]}"
      do
          case $opt in
              "Pull the latest changes")
                cd $voip_server_path
                git pull
                break
                ;;

              "voip server state")
                voip_server_state
                break
                ;;

              "Edit env")
                edit_env
                break
                ;;

              "extract node_modules")
                tar xf $voip_server_path/node_modules.tar.gz -C $voip_server_path
                break
                ;;

              "pack node_modules")
                tar -czvf $voip_server_path/node_modules.tar.gz -C $voip_server_path
                break
                ;;
            
              "Delete the project")
                  read -p "Are you sure you want to delete the project? Type CONFIRM to confirm: " confirm
                  if [[ $confirm =~ ^[Cc][Oo][Nn][Ff][Ii][Rr][Mm]$ ]]; then
                      rm -rf $voip_server_path
                  else
                      echo "Deletion cancelled"
                  fi
                  break
                  ;;

              "copy resources")
                  read -p "Are you sure you want to copy resources(all old resources rewriting!!!)? Type CONFIRM to confirm: " confirm
                  if [[ $confirm =~ ^[Cc][Oo][Nn][Ff][Ii][Rr][Mm]$ ]]; then
                      curl -X GET http://localhost:2030/api/managment/copy-resources
                  else
                      echo "copy resources cancelled"
                  fi
                  break
                  ;;

              "update scripts")
                  read -p "Are you sure you want to update scripts(Changes made cannot be reversed!!!)? Type CONFIRM to confirm: " confirm
                  if [[ $confirm =~ ^[Cc][Oo][Nn][Ff][Ii][Rr][Mm]$ ]]; then
                      #TODO: add backup option && option for change port
                      curl -X GET http://localhost:2030/api/managment/update-scripts
                  else
                      echo "update scripts cancelled"
                  fi
                  break
                  ;;

              "Exit")
                  exit 0
                  ;;
              *) echo "Invalid option $REPLY";;
          esac
      done
  fi
	read
}

function voip_server_state {
  # Check if pm2 is installed
  if ! command -v pm2 &> /dev/null; then
    echo "pm2 is not installed."
    echo "Do you want to setup pm2? (y/n)"
    read -r setup_pm2
    if [[ "$setup_pm2" =~ ^[Yy]$ ]]; then
      install_pm2
      echo "pm2 has been installed."
    else
      echo "pm2 is required to run the voip_server application. Please install pm2 and try again."
      exit 1
    fi
  fi

  # Check if voip_server is running in pm2
  if pm2 list | grep -q "voip_server"; then
    echo "voip_server is already running in pm2"
    echo "Do you want to restart voip_server? (y/n)"
    read -r restart_voip_server
    if [[ "$restart_voip_server" =~ ^[Yy]$ ]]; then
      pm2 restart voip_server
      echo "voip_server has been restarted in pm2"
    fi
  else
    cd "$voip_server_path"
    pm2 start server.js --name voip_server
    pm2 startup > /dev/null 2>&1
    pm2 save > /dev/null 2>&1
    echo "voip_server has been started in pm2"
  fi
}

function edit_env {
	# Check if .env file exists
	if [ -f $voip_server_path.env ]; then
	  echo ".env file exists"
	else
	  if [ -f $voip_server_path.envSample ]; then
		# Copy .envSample to .env
		cp $voip_server_path.envSample $voip_server_path.env
	  else
		echo ".envSample file does not exist"
		exit 1
	  fi
	fi
	
	source $voip_server_path.env

	sed -i 's/ *= */=/g' $voip_server_path.env

	declare -A env=()

	while true; do 
          clear
	  n=0 

	  select line in $(grep '^[[:alnum:]]' $voip_server_path.env); do # Use grep to filter out lines starting with # or empty  
		if [ -n "$line" ]; then 
		  key=$(echo "$line" | cut -d '=' -f1) 
		  value=$(echo "$line" | cut -d '=' -f2) 
		  echo "Current $key: $value" 
		  if [[ $value == *"'"* ]] || [[ $value == *"\""* ]]; then
			read -p "Enter new $key or press enter to keep it: " new_value
			if [ -n "$new_value" ]; then
			  if [[ $new_value != *"'"* ]] && [[ $new_value != *"\""* ]] ; then
				sed -i "s/^$key=.*/$key='$new_value'/" $voip_server_path.env
			  else
				sed -i "s/^$key=.*/$key=$new_value/" $voip_server_path.env
			  fi
			  env[$key]=$new_value
			  source $voip_server_path.env
			  echo "Saved changes."
			else
			  echo "Keeping old value."
			fi
		  else
			read -p "Enter new $key or press enter to keep it: " new_value
			if [ -n "$new_value" ]; then
			  sed -i "s/^$key=.*/$key=$new_value/" $voip_server_path.env
	  
			  env[$key]=$new_value
			  source $voip_server_path.env
			  echo "Saved changes."
			else
			  echo "Keeping old value."
			fi
		  fi
		  break   
		else      
		  echo "Exiting."     
		  break 2  
		fi      
	  done
	  clear      
	done      
	echo "Done."

}

setup_network() {
  find /etc/sysconfig/network-scripts/ -name "ifcfg-*" -type f -exec sed -i 's/ONBOOT=no/ONBOOT=yes/g' {} \;
  printf  "${Green}network boot active\n${Color_Off}"
}

correct_timezone(){
  zic asia > /dev/null 2>&1
  zic -l Asia/Tehran > /dev/null 2>&1
  sudo timedatectl set-timezone Asia/Tehran
  
  printf  "${Green}time zone has been corrected\n${Color_Off}"
}


########################################################

setup_new_project() {
  
  install_dependencies
  create_db
}

update_centos(){
  update
}

install_dependencies() { 
  install_packages 
  install_node
  install_pm2
  install_git_v2
}

create_db() {
  create_mysql_db
}

remove_setup_folder(){
  cd script_path
  cd ../
  rm -rf voip_server_initial_setup
}

update_script(){
  cd $script_path
  git pull
}

cd $script_path


########################################################

printf "${Green}\n=========================START==============================\n${Color_Off}"

while true; do
    printf "${Cyan}"
    echo "Menu:"
    echo "1) setup new"
    echo "2) update centos(need internet)"
    echo "3) setup dependencies"
    echo "4) create ebtekar db"
    echo "5) setup voip server"
    echo "6) set network boot active"
    echo "7) correct timezone"
    echo "8) install git"
    echo "9) check update"
    echo "0) Exit"
    read -p "Enter your choice: " choice
        
    tput cuu 8 && tput ed && printf "${Color_Off}\n"

    case $choice in
        1) printf "${Cyan}setup new${Color_Off}\n" && setup_new_project ;;
        2) printf "${Cyan}update centos(need internet)${Color_Off}\n" && update_centos ;;
        3) printf "${Cyan}setup dependencies${Color_Off}\n" && install_dependencies ;;
        4) printf "${Cyan}create ebtekar db${Color_Off}\n" && create_db ;;
        5) printf "${Cyan}restore database${Color_Off}\n" && setup_voip_server ;;
        6) printf "${Cyan}setup network${Color_Off}\n" && setup_network ;;
        7) printf "${Cyan}correct timezone${Color_Off}\n" && correct_timezone ;;
        8) printf "${Cyan}install git${Color_Off}\n" && install_git_v2 ;;
        9) printf "${Cyan}check update${Color_Off}\n" && update_script ;;
        0) break ;;
        *) echo "Invalid choice";;
    esac

    printf "\n"
done



printf "${Green}\n=========================DONE==============================\n${Color_Off}"



