#!/bin/sh
#
# This script allows you to install Nubomedia PaaS API. To execute it:
#
# 'curl -fsSkL https://raw.githubusercontent.com/fhg-fokus-nubomedia/bootstrap/master/bootstrap | bash'

. /lib/lsb/init-functions

#general configuration
_PROJECT_NAME="nubomedia-paas"
_BASE="/opt"
_PROJECT_ROOT_BASE="${_BASE}/nubomedia"
_PROJECT_BASE="${_PROJECT_ROOT_BASE}/${_PROJECT_NAME}"
_PROJECT_PROPERTIES_FOLDER="/etc/nubomedia"
_DEFAULT_PROPERTIES_FILE="${_PROJECT_BASE}/etc/paas.properties"
_PROJECT_PROPERTIES_FILE="${_PROJECT_PROPERTIES_FOLDER}/paas.properties"
_PROJECT_LOG_FOLDER="/var/log/nubomedia"

_DATABASE_NAME="nubomediapaas"

#debian configuration
_APT_KEY_SERVER="keyserver.ubuntu.com"
_APT_KEY_SERVER_KEY="F04B5A6F"
_APT_REPOSITORY="deb http://repository.nubomedia.eu/ trusty main"

#git configuration
_PROJECT_REPO="https://github.com/fhg-fokus-nubomedia/nubomedia-paas.git"
_SCRIPT_NAME="nubomedia-paas.sh"
_TAG="develop"
#_TAG="tags/1.1"

_USER="$(id -un 2>/dev/null || true)"

checkBinary () {
  if command -v $1 >/dev/null 2>&1 ; then
      log_success_msg "Checking for '$1'"
      return 0
  else
      log_failure_msg "Checking for '$1'"
      return 1
  fi
}

_ex='sh -c'
if [ "$_USER" != 'root' ]; then
    if checkBinary sudo; then
        _ex='sudo -E sh -c'
    elif checkBinary su; then
        _ex='su -c'
    fi
fi

# Checks if the function call of setting properties got the expected values
# $1: description shown for entering value (mandatory)
# $2: configuration property (mandatory)
# $3: default configuration value (optional)
checkPropertyConfiguration () {
    # Checking if the description is given
    if [ -z "$1" ]; then
      echo "-Parameter #1 is not set. Please provide the description of this configration parameter."
      return 1
    # Checking if the configuration parameter is given
    elif [ -z "$2" ]; then
      echo "-Parameter #2 is not set. Please provide the configration parameter."
      return 1
    fi
    # Reading the value from the user
    export _VALUE
    read -p "$1 [$3]:" _VALUE
    # Checking if at least one of both values is defined (either default or defined)
    if [ -z "${_VALUE}" ] && [ -z "${3}" ]; then
        log_failure_msg "You have to provide a value for \"$2\" since there is no default"
        checkPropertyConfiguration "$1" "$2" "$3"
    elif [ ! -z "${_VALUE}" ]; then
        setProperty $2 $_VALUE
        log_success_msg "Set parameter \"$2\" to value \"$_VALUE\""
    elif [ ! -z "${3}" ]; then
        setProperty $2 $3
        log_success_msg "Kept parameter \"$2\" as the default value \"$3\""
    fi
}

# Set the properties in the configuration file (no further checks)
# $1: configuration property (mandatory)
# $2: configuration property value (mandatory)
setProperty () {
    $_ex 'sed -i "s/^'"$1"'=.*/'"$1"'="'$2'"/g" '"$_PROJECT_PROPERTIES_FILE"
}

#property configuration
configureProperties () {
    echo "The properties file to change is: $_PROJECT_PROPERTIES_FILE"

    echo "NUBOMEDIA PaaS-Manager configuration"
    checkPropertyConfiguration "Enter the port of the PaaS Manager" "paas.port" "8081"
    echo
    echo "OpenShift configuration"
    checkPropertyConfiguration "Enter the OpenShift url" "openshift.baseURL" ""
    checkPropertyConfiguration "Enter the domain name for the applications" "openshift.domainName" ""
    checkPropertyConfiguration "Enter the project name to be used in OpenShift" "openshift.project" ""
    checkPropertyConfiguration "Enter the token to be used to authorize against OpenShift" "openshift.token" ""
    checkPropertyConfiguration "Enter the keystore to be used to authenticate against OpenShift" "openshift.keystore" ""
    echo
    echo "KMS image configuration"
    checkPropertyConfiguration "Enter the name of the image to be used for the KMS instances" "kms.image" "kurento-media-server"
    checkPropertyConfiguration "Enter the IP of the NFVO" "nfvo.ip" "localhost"
    checkPropertyConfiguration "Enter the port of the NFVO" "nfvo.port" "8080"
    echo
    echo "NFVO configuration"
    checkPropertyConfiguration "Enter the username to authorize against the Orchestrator" "nfvo.username" "admin"
    checkPropertyConfiguration "Enter the password to authorize against the Orchestrator" "nfvo.password" ""
    echo
    echo "Media Server VNF Manager configuration"
    checkPropertyConfiguration "Enter the IP of the VNFM" "vnfm.ip" "localhost"
    checkPropertyConfiguration "Enter the port of the VNFM" "vnfm.port" "9000"
    echo
    echo "Marketplace configuration"
    checkPropertyConfiguration "Enter the IP of the marketplace" "marketplace.ip" "localhost"
    checkPropertyConfiguration "Enter the port of the marketplace" "marketplace.port" "8082"
    echo
    echo "VIM configuration"
    checkPropertyConfiguration "Enter the Auth URL of the cloud infrastructure" "vim.authURL" ""
    checkPropertyConfiguration "Enter the tenant name to be used in your cloud infrastructure" "vim.tenant" ""
    checkPropertyConfiguration "Enter the username to be used to authorize against your cloud infrastructure (VIM)" "vim.username" ""
    checkPropertyConfiguration "Enter the password to be used to authorize against your cloud infrastructure (VIM)" "vim.password" ""
    checkPropertyConfiguration "Enter the Key file to be used to login to the VMs via ssh" "vim.keypair" ""
}

##################
#### database ####
##################

configureDatabase () {
    echo "Do you wish to use MySQL?"
    echo "1) Yes"
    echo "2) No (default)"
    read -p "Your choice: " choice
    case $choice in
        1) installMySql
        configureMySql;;
        2) return 0;;
        *) return 0;;
    esac
}

###############
#### MySQL ####
###############

installMySql () {
    checkBinary mysql; _error=$(($_error + $?))
    if [ "0" != "$_error" ]; then
        log_warning_msg "MySQL is not yet installed. Start installation ..."
        $_ex 'apt-get -y install mysql-server'
    fi
}

#requests the MySQL root password
#additionally, it checks if the root password is valid
#if not, it is asked again for the right password
getMySqlRootPw () {
    stty -echo
    read -p "Please, provide the password of the root user of mysql: " rootpasswd; echo
    stty echo
    #for empty passwords it is also allowed
    #if [ -z "${rootpasswd}" ]; then
    #    log_failure_msg "You have to provide the root password of MySQL..."
    #    getMySqlRootPw
    #    return 0
    #fi
    #check if root password is correct
    mysql -uroot -p${rootpasswd} -e exit
    if [ $? -eq 0 ]; then
        log_success_msg "MySQL root password validated"
    else
        log_failure_msg "MySQL root password is wrong ..."
        getMySqlRootPw
        return 0
    fi
}

#creates a new MySQL user
#should always work since it is checked before that the user does not exist
createMySqlUser () {
    mysql -uroot -p${rootpasswd} -e "CREATE USER ${sqlUser}@localhost IDENTIFIED BY \"${sqlPassword}\""
    if [ $? -eq 0 ]; then
        log_success_msg "Created user"
    else
        log_failure_msg "Failed to create new MySQL user ${sqlUser}"
        exit 1
    fi
}

#Checks if the database exists already
#if not, it is created a new
#if yes, it can be decided to keep the database or drop it and create a new one
createMySqlDatabase () {
    exist=`mysql -uroot -p*4root# -e "show databases;" | grep "\b${_DATABASE_NAME}\b" | wc -l`
    if [ ${exist} -eq 1 ]; then
        echo "MySQL database ${_DATABASE_NAME} exists already"
        echo "How to proceed?"
        echo "1) Keep it (default)"
        echo "2) Drop it"
        read -p "Your choice: " choice
        case $choice in
            1) return 0;;
            2) mysql -uroot -p*4root# -e "drop database ${_DATABASE_NAME};"
            log_success_msg "Dropped database ${_DATABASE_NAME}"
            createMySqlDatabase;;
            *) return 0;;
        esac
    else
        mysql -uroot -p${rootpasswd} -e "CREATE DATABASE ${_DATABASE_NAME} /*\!40100 DEFAULT CHARACTER SET utf8 */;"
        log_success_msg "Created new database ${_DATABASE_NAME}"
    fi
}

#configures the database table for the given user
assignMySqlDatabaseRights () {
    mysql -uroot -p${rootpasswd} -e "GRANT ALL ON ${_DATABASE_NAME}.* TO '${sqlUser}'@'localhost';"
    log_success_msg "Granted rights to user ${sqlUser}"
    mysql -uroot -p${rootpasswd} -e "FLUSH PRIVILEGES;"
    log_success_msg "Flushed privileges"
    mysql -uroot -p${rootpasswd} -e "USE ${_DATABASE_NAME};"
    log_success_msg "Changed to database ${_DATABASE_NAME}"
}

#checks if the user exists and credentials are valid
#if the user exist but the password is wrong it goes back to enter the credentials
#if the user doesn't exist, it is created a new one
checkIfMySqlUserExist () {
    echo "Checking if user already exists ..."
    exist=`mysql -uroot -p${rootpasswd} -e "select * from mysql.user;" | grep "\b${sqlUser}\b" | wc -l`
    if [ ${exist} -eq 1 ]; then
        echo "MySQL user ${sqlUser} exists already. Checking password..."
        mysql -u${sqlUser} -p${sqlPassword} -e exit
        if [ $? -eq 0 ]; then
            log_success_msg "MySQL password for user ${sqlUser} validated"
            return 0
        else
            log_failure_msg "MySQL password for user ${sqlUser} is wrong ..."
            requestMySqlUser
        fi
    else
        echo "Creating a new MySQL user with name ${sqlUser} ..."
        createMySqlUser
        return 0
    fi

}

#reqeusts the user that should be used for MySQL
#additionally, it will be checked if the user exists and can login
requestMySqlUser () {
    read -p "Please, enter the name of the mysql user you would like ${_PROJECT_NAME} to use [admin]: " sqlUser
    if [ -z "$sqlUser" ]; then
        sqlUser=admin
    fi
    # Turning echo on and off between password reading
    stty -echo
    read -p "Please, provide the password for this user [changeme]: " sqlPassword; echo
    if [ -z "$sqlPassword" ]; then
        sqlPassword=changeme
    fi
    stty echo
    checkIfMySqlUserExist
}

#configuring MySQL in the properties file
#Enabling MySQL, disabling HSQL
configureMySql () {
    echo "Configuring MySQL for $_PROJECT_NAME ..."
    # Request MySQL root password to configure a new user for MySQL
    getMySqlRootPw
    # Request MySQL to use for this project
    requestMySqlUser
    # Create the Database
    createMySqlDatabase
    assignMySqlDatabaseRights
    $_ex 'sed -i "s/^spring.jpa.hibernate.ddl-auto=create-drop/spring.jpa.hibernate.ddl-auto=update/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^#spring.datasource.validationQuery=.*/spring.datasource.validationQuery=SELECT 1/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^#spring.datasource.testOnBorrow=.*/spring.datasource.testOnBorrow=true/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^#.*spring.datasource.url=.*/spring.datasource.url=jdbc:mysql:\/\/localhost:3306\/'"$_DATABASE_NAME"'/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^#.*spring.datasource.driver-class-name=com.mysql.jdbc.Driver/spring.datasource.driver-class-name=com.mysql.jdbc.Driver/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^#.*spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect/spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^s.*pring.datasource.username=.*/spring.datasource.username='"${sqlUser}"'/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^s.*pring.datasource.password=.*/spring.datasource.password='"${sqlPassword}"'/g" '"$_PROJECT_PROPERTIES_FILE"
    log_success_msg "Enabled MySQL"
    $_ex 'sed -i "s/^spring.datasource.url=jdbc:hsqldb:file:\(.*\)/#spring.datasource.url=jdbc:hsqldb:file:\1/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver/#spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect/#spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect/g" '"$_PROJECT_PROPERTIES_FILE"
    log_success_msg "Disabled HSQL"
}

##################
#### RabbitMQ ####
##################

configureRabbitMQ () {
    checkPropertyConfiguration "Enter the host address where the RabbitMQ server is running" "rabbitmq.host" "localhost"
    checkPropertyConfiguration "Enter the username used to authorize against the RabbitMQ server" "rabbitmq.username" ""
    checkPropertyConfiguration "Enter the password used to authorize against the RabbitMQ server" "rabbitmq.password" ""
}

######################
#### Using DEBIAN ####
######################

#adding apt repository
#1. add key
#2. add repo
#3. update repositories
addAptRepository () {
    if [ -z "$_APT_KEY_SERVER_KEY" ] && [ -z "$_APT_KEY_SERVER" ]; then
        log_warning_msg "Either the key server or key for the key server was not defined. Continue with adding the apt repository"
    else
        echo "Adding key server and key..."
        $_ex 'apt-key adv --keyserver '"$_APT_KEY_SERVER"' --recv-keys '"$_APT_KEY_SERVER_KEY"
    fi
    if [ -n "$_APT_REPOSITORY" ]; then
        echo "Adding apt repository..."
        $_ex 'add-apt-repository '"\"$_APT_REPOSITORY\""
    else
        log_error_msg "apt repository is null. Please provide"
    fi
    $_ex 'apt-get update -y'
}

#isntalls the project
installProject () {
    $_ex 'apt-get install -y '"$_PROJECT_NAME"
}

#debian re-start of the project
restartProject () {
    instance=$(ps aux | grep -v grep | grep "$_PROJECT_NAME" | grep jar | wc -l)
    if [ ${instance} -ne 0 ] ; then
        echo "restarting $_PROJECT_NAME ..."
        "$_PROJECT_NAME" restart
    else
        echo "starting $_PROJECT_NAME ..."
        "$_PROJECT_NAME" start
    fi

}

#########################################
########## Using source code ############
#########################################

prereq () {
  $_ex 'apt-get update; apt-get -y install openjdk-7-jdk screen git rabbitmq-server'
  log_success_msg "Installed required software"
}

checkEnvironment () {
  _error=0
  echo "Checking environment..."
  checkBinary java; _error=$(($_error + $?))
  checkBinary javac; _error=$(($_error + $?))
  checkBinary curl; _error=$(($_error + $?))
  checkBinary screen; _error=$(($_error + $?))
  checkBinary wget; _error=$(($_error + $?))
  if [ "0" != "$_error" ]; then
    log_failure_msg "FAILED. Please install the above mentioned binaries."
    exit 1
  fi
}

configureRabbitMq () {
    # Allow the use of the .deb package to install Open Baton with Docker (because of issues when installing and configuring RabbitMQ during a docker image build)
    # See documentation for more info
    echo "Creating RabbitMQ user \"${_PROJECT_NAME}\""
    result=`$_ex 'rabbitmqctl list_users' | grep '^'"$_PROJECT_NAME" | wc -l`
    if [ ${result} -eq 0 ]; then
        rabbitMqPassword=`< /dev/urandom tr -dc A-Z-a-z-0-9 | head -c${1:-32};echo;`
        $_ex 'rabbitmqctl add_user '"$_PROJECT_NAME"' '"$rabbitMqPassword"
        log_success_msg "Created RabbitMQ user \"${_PROJECT_NAME}\""
    else
        log_warning_msg "User \"${_PROJECT_NAME}\" exists already"
        rabbitMqPassword=`< /dev/urandom tr -dc A-Z-a-z-0-9 | head -c${1:-32};echo;`
        $_ex 'rabbitmqctl change_password '"$_PROJECT_NAME"' '"$rabbitMqPassword"
        log_success_msg "Changed password of RabbitMQ user \"${_PROJECT_NAME}\""
    fi
    $_ex 'rabbitmqctl set_user_tags '"$_PROJECT_NAME"' administrator'
    $_ex 'rabbitmqctl set_permissions -p / '"$_PROJECT_NAME"' ".*" ".*" ".*"'
    $_ex 'sed -i "s/^rabbitmq.username=.*/rabbitmq.username='"$_PROJECT_NAME"'/g" '"$_PROJECT_PROPERTIES_FILE"
    $_ex 'sed -i "s/^rabbitmq.password=.*/rabbitmq.password='"$rabbitMqPassword"'/g" '"$_PROJECT_PROPERTIES_FILE"
    log_success_msg "Changed RabbitMQ user in ${_PROJECT_PROPERTIES_FILE}"
    #### Workaround to enable rabbitmq management plugin ####
    #$_ex 'rabbitmq-plugins enable rabbitmq_management'
    if [ -f /etc/rabbitmq/enabled_plugins ]; then
        result=$(grep /etc/rabbitmq/enabled_plugins -e "[rabbitmq_management].")
        if [ "${result}" != "[rabbitmq_management]." ]; then
            $_ex 'echo "[rabbitmq_management]." >> /etc/rabbitmq/enabled_plugins'
        fi
    else
        $_ex 'echo "[rabbitmq_management]." > /etc/rabbitmq/enabled_plugins'
    fi
    ##########################################################
    $_ex 'service rabbitmq-server restart'
    if [ "$?" != "0" ]; then
        log_failure_msg "rabbitmq is not running properly (check the problem in /var/log/rabbitmq)"
        exit 1
    fi
}

#create the base where the project is cloned to
createBase () {
    echo "Creating the ${_PROJECT_NAME} root base folder \"${_PROJECT_ROOT_BASE}\""
    if [ -d "${_PROJECT_ROOT_BASE}" ]; then
        if [ -d "${_PROJECT_BASE}" ]; then
            echo "Base folder \"${_PROJECT_BASE}\" exists already"
            echo "How to proceed?"
            echo "1) Keep it"
            echo "2) Remove it (default)"
            read -p "Your choice: " choice
            case $choice in
                1) return 0;;
                2) $_ex 'rm -rf '"$_PROJECT_BASE"
                log_success_msg "Removed old base folder";;
                *) $_ex 'rm -rf '"$_PROJECT_BASE"
                log_success_msg "Removed old base folder";;
            esac
        fi
    else
       $_ex 'mkdir -p '"$_PROJECT_ROOT_BASE"
       log_success_msg "Created root base folder \"${_PROJECT_ROOT_BASE}\""
    fi
    $_ex 'chown -R '"$_USER $_PROJECT_ROOT_BASE"
    log_success_msg "Configured permissions of root base folder \"${_PROJECT_ROOT_BASE}\""
}

createLogFolder () {
    # create log folder and give permission
    if [ -d "${_PROJECT_LOG_FOLDER}" ]; then
        echo "Log folder \"${_PROJECT_LOG_FOLDER}\" exists already"
        echo "How to proceed?"
        echo "1) Keep it (default)"
        echo "2) Remove it"
        read -p "Your choice: " choice
        case $choice in
            1) return 0;;
            2) $_ex 'rm -rf '"$_PROJECT_LOG_FOLDER"
            log_success_msg "Removed log folder \"${_PROJECT_LOG_FOLDER}\""
            $_ex 'mkdir -p '"$_PROJECT_LOG_FOLDER"
            log_success_msg "Created log folder \"${_PROJECT_LOG_FOLDER}\"";;
            *) return 0;;
        esac
    else
        $_ex 'mkdir -p '"$_PROJECT_LOG_FOLDER"
        log_success_msg "Created log folder \"${_PROJECT_LOG_FOLDER}\""
    fi
    $_ex 'chown -R '"$_USER $_PROJECT_LOG_FOLDER"
    log_success_msg "Configured permissions of log folder \"${_PROJECT_LOG_FOLDER}\""
}

setPassword () {
    stty -echo
    read -p "Provide the new password of admin user of $_PROJECT_NAME: " password ; echo
    stty echo
    if [ "${password}" != "" ]; then
        export password=${password}
        stty -echo
        read -p "Repeat the password: " password2 ; echo
        stty echo
        export password2=${password2}
        if [ "${password}" = "${password2}" ]; then
            $_ex 'sed -i "s/paas.security.admin.password=.*/paas.security.admin.password='"$password"'/g" '"${_PROJECT_PROPERTIES_FILE}"
            log_success_msg "Set admin password"
        else
            log_failure_msg "Passwords didn't match. Try again ..."
            setPassword
        fi
    else
        log_warning_msg "Admin password must be provided ..."
        setPassword
    fi
}

cloneProject () {
    echo "Cloning ${_PROJECT_NAME} to ${_PROJECT_BASE} ..."
    oldpath=`pwd`
    cd "${_PROJECT_ROOT_BASE}"
    git clone --recursive "${_PROJECT_REPO}" "${_PROJECT_NAME}"
    cd $oldpath
}

checkoutVersion () {
    echo "Choose version:"
    echo "1) ${_TAG} (default)"
    echo "2) master"
    echo "3) develop"
    read -p "Your choice: " choice
    case $choice in
        1) version=${_TAG};;
        2) version=master;;
        3) version=develop;;
        *) version=${_TAG};;
    esac
    oldpath=`pwd`
    cd "${_PROJECT_BASE}"
    git checkout ${version}
    cd $oldpath
}

copyConfigFiles () {
    if [ ! -d "${_PROJECT_PROPERTIES_FOLDER}" ]; then
        $_ex 'mkdir -p '"${_PROJECT_PROPERTIES_FOLDER}"
        log_success_msg "created properties folder"
    else
        log_warning_msg "Properties folder \"${_PROJECT_PROPERTIES_FOLDER}\" exists already"    
    fi
    $_ex 'cp '"${_DEFAULT_PROPERTIES_FILE} ${_PROJECT_PROPERTIES_FILE}"
    log_success_msg "Copied default configuration file \"${_DEFAULT_PROPERTIES_FILE}\" to \"${_PROJECT_PROPERTIES_FOLDER}\""
    if [ -d "${_PROJECT_BASE}/etc" ]; then
        $_ex 'cp '"${_PROJECT_BASE}/etc/* ${_PROJECT_PROPERTIES_FOLDER}"
        log_success_msg "Copied files from \"${_PROJECT_BASE}/etc\" to \"${_PROJECT_PROPERTIES_FOLDER}\""
    fi
}

compileProject () {
    echo "Compiling ${_PROJECT_NAME}"
    oldpath=`pwd`
    cd "${_PROJECT_BASE}"
    ./${_SCRIPT_NAME} compile
    if [ $? -ne 0 ]; then
        echo "ERROR: The compilation of ${_PROJECT_NAME} failed"
        exit 1
    fi
    cd $oldpath
}

startProject () {
    echo "Starting ${_PROJECT_NAME}"
    oldpath=`pwd`
    cd ${_PROJECT_BASE}
    ./${_SCRIPT_NAME} start
    cd $oldpath
}

#################
### INSTALLER ###
#################

useDebian () {
    #Add apt repository
    addAptRepository
    #Install project
    installProject
    #ask/configure mysql
    configureDatabase
    #configure properties
    configureProperties
    #start or restart project
    restartProject
}

useSourceCode () {
    prereq
    checkEnvironment
    createBase
    createLogFolder
    cloneProject
    checkoutVersion
    copyConfigFiles
    setPassword
    configureRabbitMq
    configureDatabase
    configureProperties
    compileProject
    startProject            
}

bootstrap () {
    echo "How to install ${_PROJECT_NAME}?"
    echo "1) debian (default)"
    echo "2) source code via git"
    read -p "Your choice: " choice
    case $choice in
        1) useDebian;;
        2) useSourceCode;;
        *) useDebian;;
    esac
    echo "$_PROJECT_NAME is up and running now..."
}

bootstrap