#!/bin/bash

cd /root

MONGOSH_BIN="/usr/local/jetapps/usr/bin/mongosh"
AUTH_FILE="/usr/local/jetapps/etc/.mongod.auth"
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'

[[ ! -f /etc/os-release ]] && echo "Can't find /etc/os-release file" && exit 1

echo "Installing jetmongod-remote package..."

source /etc/os-release

if [[ -x "$(command -v yum)" || -x "$(command -v dnf)" ]]; then
	yum clean all --disablerepo=* --enablerepo=jetapps >/dev/null
	yum -y -q install jetmongod-remote --disablerepo=* --enablerepo=jetapps >/dev/null
elif [[ -x "$(command -v apt-get)" ]]; then
	apt update >/dev/null
	apt install -y jetmongod-remote >/dev/null
else
	echo "[ERROR] Failed fetching package manager." >&2
	exit 1
fi

if [[ ! -f "$MONGOSH_BIN" ]]; then
	echo "[ERROR] Failed install jetmongod-remote package." >&2
	exit 1
fi

echo "Select Environment:"
echo "1) Standard (Local/Remote)"
echo "2) MongoDB Atlas (SRV)"
echo "3) AWS DocumentDB / Custom TLS"
read -e -p "Choice [1-3]: " ENV_TYPE
read -e -p "Enter MongoDB database username: " DB_USER
read -e -s -p "Enter MongoDB database Password: " DB_PASS
echo ""
read -e -p "Enter MongoDB authentication database: " AUTH_DB
read -e -p "Enter MongoDB database name: " DB_NAME
read -e -p "Enter MongoDB server host: " DB_HOST

CA_FILE=""
DB_PORT=""
if [[ "$ENV_TYPE" == "3" ]]; then
	read -e -p "Path to CA File (optional, leave blank if none): " CA_FILE
fi

# Percent-encode a value without exposing it in argv
urlencode() {
	VALUE="$1" "$MONGOSH_BIN" --nodb --quiet --eval 'print(encodeURIComponent(process.env.VALUE))'
}

ENC_USER=$(urlencode "$DB_USER")
ENC_PASS=$(urlencode "$DB_PASS")

URI_OPTS="authSource=$(urlencode "$AUTH_DB")"
if [[ -n "$CA_FILE" ]]; then
	URI_OPTS+="&tls=true&tlsCAFile=$(urlencode "$CA_FILE")"
fi

if [[ "$ENV_TYPE" == "2" ]]; then
	PROTOCOL="mongodb+srv://"
	URI="${PROTOCOL}${ENC_USER}:${ENC_PASS}@${DB_HOST}/?${URI_OPTS}"
else
	read -e -p "Enter MongoDB server port: " DB_PORT
	PROTOCOL="mongodb://"
	URI="${PROTOCOL}${ENC_USER}:${ENC_PASS}@${DB_HOST}:${DB_PORT}/?${URI_OPTS}"
fi

# Secrets travel via the environment, never the command line
run_mongosh() {
	MONGO_URI="$URI" TARGET_DB="$DB_NAME" "$MONGOSH_BIN" --nodb --quiet --eval "$1"
}

echo -e "\nTesting Connection..."

CHECK_SCRIPT='
  try {
    const target = connect(process.env.MONGO_URI).getSiblingDB(process.env.TARGET_DB);
    if (target.runCommand({ping: 1}).ok === 1) print("PING_OK");
    if (Array.isArray(target.getCollectionNames())) print("ACCESS_OK");
  } catch (e) {
    print(e.message);
  }
'

RESULT=$(run_mongosh "$CHECK_SCRIPT" 2>&1)

if [[ $RESULT != *"PING_OK"* ]]; then
	echo -e "[ERROR] ${RED}Connection Failed${NC}" >&2
	echo "$RESULT" >&2
	exit 1
fi

if [[ $RESULT != *"ACCESS_OK"* ]]; then
	echo -e "[ERROR] ${RED}Permission Denied${NC}" >&2
	echo "The user is authenticated, but does not have 'find' permissions on database: '$DB_NAME'" >&2
	exit 1
fi

HOSTNAME_SCRIPT='
  const target = connect(process.env.MONGO_URI).getSiblingDB(process.env.TARGET_DB);
  print(target.getCollection("config").findOne({_id: "general"})?.hostname || "");
'

INSTALLATION_HOSTNAME=$(run_mongosh "$HOSTNAME_SCRIPT" 2>/dev/null)

if [[ "$INSTALLATION_HOSTNAME" && "$INSTALLATION_HOSTNAME" != "$(hostname)" ]]; then
	echo -e "[ERROR] ${RED}Database Namespace Conflict${NC}" >&2
	echo "The specified database is already linked to another server instance: '$INSTALLATION_HOSTNAME'." >&2
	echo "Cross-installation database sharing is not supported." >&2
	echo "Solution: Please provide a fresh database or clear the existing one before proceeding." >&2
	exit 1
fi

old_umask=$(umask)
umask 077

sudo tee "$AUTH_FILE" >/dev/null <<EOF
HOST=$DB_HOST
PORT=$DB_PORT
USER=$DB_USER
PASS=$DB_PASS
DB=$DB_NAME
AUTHDB=$AUTH_DB
PROTOCOL=$PROTOCOL
CA=$CA_FILE
URI=$URI
EOF

# umask only applies to new files; enforce the mode if the file already existed
sudo chmod 0600 "$AUTH_FILE"

umask "$old_umask"

echo -e "${GREEN}Database configuration successful!${NC}"
echo "You can now proceed with the application installation; it will use the authenticated database details provided."
exit 0
