#!/usr/bin/bash
set -e

RED='\033[0;31m'
NC='\033[0m'
IWHITE='\033[0;97m'

sudo yum install jq -y

sudo yum install java-21-openjdk-devel

# Function to parse JSON without jq
parse_json() {
    local json="$1"
    local query="$2"
    echo "$json" | jq -r "$query"
}

generate_unique_id() {
    echo $((RANDOM + 10000))
}

remove_license_markers() {
    local license_content="$1"
    # Remove license markers and clean the content
    echo "$license_content" | awk '
    BEGIN { 
        RS="-----END LICENSE FILE-----";
        FS="-----BEGIN LICENSE FILE-----";
    }
    {
        gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2);
        gsub(/\n/, "", $2);
        print $2;
    }'
}

# Find the first .out file in the current directory
LICENSE_FILE=$(ls *.out 2>/dev/null | head -n 1)

if [ -z "$LICENSE_FILE" ]; then
    echo "Error: No .out file found in the current directory."
    exit 1
fi

echo "Using license file: $LICENSE_FILE"

# Read the license string from the .out file
LICENSE_STRING=$(cat "$LICENSE_FILE")

# Compile and run LicenseParser
mkdir -p com/authentrend/licenseparser
cp LicenseParser.java com/authentrend/licenseparser/
javac -cp "./libs/*" com/authentrend/licenseparser/LicenseParser.java

# Create a temporary file for the license string
TEMP_LICENSE_FILE=$(mktemp)
echo "$LICENSE_STRING" > "$TEMP_LICENSE_FILE"

# Run the Java program with the temporary file
# -cp .:./libs/*: This sets the classpath for the Java runtime.
#   -cp is short for -classpath
#   . includes the current directory in the classpath
#   ./libs/* includes all JAR files in the libs directory
#   The colon : separates these two classpath entries

parse_result=$(java -cp .:./libs/* com.authentrend.licenseparser.LicenseParser "$TEMP_LICENSE_FILE")

# Remove the temporary file
rm "$TEMP_LICENSE_FILE"

# Clean up compiled files
rm -rf com

# Extract AUTHFI_APIPATH and AUTHFI_ACCESSPOINT
AUTHFI_APIPATH=$(parse_json "$parse_result" '.rpData[0].authFiApiKey')
AUTHFI_URL=$(parse_json "$parse_result" '.data.authFiUrl')
AUTHFI_ACCESSPOINT=$(parse_json "$parse_result" '.rpData[0].authFiApiAccessPoint')
ATKEY_URL=$(parse_json "$parse_result" '.data.state.productState.url')
MAX_USERS=$(parse_json "$parse_result" '.data.state.productState.maxUsers')
AUTHENTICATION_LIMIT=$(parse_json "$parse_result" '.data.state.productState.authenticationLimit')
ADMIN_EMAILS=$(parse_json "$parse_result" '.data.state.productState.productAdmins')
EXPIRE_DATE=$(parse_json "$parse_result" '.data.state.productState.expireDate')
MAGIC_CODE_TEST=`echo "$parse_result" | jq -r 'select(.data.state.productState.magicCode) | .data.state.productState.magicCode'`
CURRENT_EPOCH=$(date +%s)

CLEAN_LICENSE_STRING=$(remove_license_markers "$LICENSE_STRING")


[ -z "$AUTHFI_APIPATH" ] || [ -z "$AUTHFI_ACCESSPOINT" ] && { echo "Failed to parse required values from the license."; exit 1; }

# if [ $CURRENT_EPOCH -gt $EXPIRE_DATE ]; then
#     echo "Error: The expiration date ($EXPIRE_DATE) has already passed." >&2
#     exit 1
# fi

# Update docker-compose.yml
# /AUTHFI_APIPATH=/:

# This is a pattern enclosed in forward slashes.
# In awk, when a line matches this pattern (i.e., contains the text "AUTHFI_APIPATH="), the following action in curly braces is executed.


# {$0 = "      - AUTHFI_APIPATH=" apipath}:

# This is the action to be performed when the pattern is matched.
# $0 refers to the entire current line in awk.
# = is assigning a new value to the entire line.
# "      - AUTHFI_APIPATH=" is a string literal. Note the leading spaces, which are likely for indentation in the YAML file.
# apipath is an awk variable (passed from the shell script) containing the new API path value.

if [ -f docker-compose.yml ]; then
    awk -v apipath="$AUTHFI_APIPATH" -v accesspoint="$AUTHFI_URL"/"$AUTHFI_ACCESSPOINT" -v server_url="$ATKEY_URL" '
    /SERVER_URL=/ {$0 = "      - SERVER_URL=" server_url}
    /AUTHFI_APIPATH=/ {$0 = "      - AUTHFI_APIPATH=" apipath}
    /AUTHFI_ACCESSPOINT=/ {$0 = "      - AUTHFI_ACCESSPOINT=" accesspoint}
    {print}
    ' docker-compose.yml > docker-compose.yml.tmp && mv docker-compose.yml.tmp docker-compose.yml
fi
# awk 'program' input-file > output-file

TRUSTSTORE="truststore.jks"
TRUSTSTORE_PASSWORD="changeit"

echo "Creating an empty truststore..."
keytool -genkeypair -alias dummy -keyalg RSA -keysize 2048 -keystore $TRUSTSTORE -storepass $TRUSTSTORE_PASSWORD -validity 365 -dname "CN=dummy" -keypass $TRUSTSTORE_PASSWORD

# Delete the dummy entry
echo "Removing dummy entry..."
keytool -delete -alias dummy -keystore $TRUSTSTORE -storepass $TRUSTSTORE_PASSWORD

echo "Truststore is ready for use with Docker Compose."

yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin --allowerasing
systemctl enable docker
systemctl start docker
docker run hello-world

echo "Configure firewall rules."
sudo sh -c "firewall-cmd --permanent --zone=public --add-service=http && firewall-cmd --permanent --zone=public --add-service=https && firewall-cmd --reload"
sudo sh -c "firewall-cmd --permanent --zone=public --add-port=8000/tcp && firewall-cmd --reload"
sudo sh -c "setsebool httpd_can_network_connect on -P"
sudo sh -c "setsebool httpd_can_network_connect_db on -P"

echo "Creating service file"
cat > /etc/systemd/system/atkeylogin.service << EOF
[Unit]
After=docker.service
[Service]
WorkingDirectory=/www/atkeylogin
Type=oneshot
RemainAfterExit=yes

ExecStartPre=-/usr/libexec/docker/cli-plugins/docker-compose pull
ExecStart=/usr/libexec/docker/cli-plugins/docker-compose up -d
ExecStop=/usr/libexec/docker/cli-plugins/docker-compose stop

ExecReload=-/usr/libexec/docker/cli-plugins/docker-compose pull
ExecReload=/usr/libexec/docker/cli-plugins/docker-compose up -d

Restart=on-failure
[Install]
WantedBy=multi-user.target

EOF
    # restart daemon, enable and start service
echo "Reloading daemon and enabling service"
systemctl daemon-reload 
systemctl enable atkeylogin.service
systemctl start atkeylogin.service
echo "Service Started"

# Wait for Redis container to be ready
echo "Waiting for Redis container to be ready..."
sleep 20

echo "Setting up Redis permissions..."
REDIS_UID=$(docker run --rm redis id -u redis)
REDIS_GID=$(docker run --rm redis id -g redis)

sudo mkdir -p redis-data
sudo chown -R $REDIS_UID:$REDIS_GID redis-data
sudo chmod 755 redis-data

if [ -f redis.conf ]; then
    sudo chown $REDIS_UID:$REDIS_GID redis.conf
    sudo chmod 644 redis.conf
fi

echo "Checking if license already exists in Redis..."
LICENSE_EXISTS=$(docker exec redis6969 redis-cli EXISTS license)

if [ "$LICENSE_EXISTS" -eq 0 ]; then
    echo "License does not exist. Inserting license info into Redis..."
    docker exec redis6969 redis-cli SET license "$CLEAN_LICENSE_STRING"
    docker exec redis6969 redis-cli SET maxUsers $MAX_USERS
    docker exec redis6969 redis-cli SET authenticationLimit $AUTHENTICATION_LIMIT
    docker exec redis6969 redis-cli SET curUser 0
    docker exec redis6969 redis-cli SET curAuthentications 0
    echo "License info inserted successfully."
else
    echo "License already exists in Redis. Skipping insertion."
fi

DB_CONTAINER_NAME="db"
DB_NAME="atkeylogin"
DB_USER="admin"
DB_PASSWORD="1234"
TABLE_NAME="users"
COLUMN_NAMES="id, authorities, email, groups, created_at, authorities_update_time, companioned_times, max_companion_counts"
COUNT=0
CURRENT_EPOCH_TIME=$(date +%s)

echo $ADMIN_EMAILS# Read the JSON array into a Bash array
readarray -t admin_emails < <(echo "$ADMIN_EMAILS" | jq -r '.[]')

# Loop through the array
for admin_email in "${admin_emails[@]}"; do
    id=$(generate_unique_id)
    authorities="ROLE_ADMIN"
    echo $admin_email

    INSERT_COMMAND="INSERT INTO $TABLE_NAME ($COLUMN_NAMES) VALUES ('$id', '$authorities', '$admin_email', array[]::text[], '$CURRENT_EPOCH_TIME', '$CURRENT_EPOCH_TIME', '$COUNT', '$COUNT');"

    if docker exec -i "$DB_CONTAINER_NAME" psql -U "$DB_USER" -d "$DB_NAME" -c "$INSERT_COMMAND"; then
        echo -e "Admin user ${IWHITE}$admin_email${NC} inserted successfully."
    else
        echo -e "Failed to insert admin user ${IWHITE}$admin_email${NC}."
    fi
done

if [ -z "${MAGIC_CODE_TEST}" ]; then
	echo -e "Please enter ${IWHITE}244691${NC} as the recovery verification code."
	docker exec redis6969 redis-cli DEL magicCode 2>&1 > /dev/null
else
	echo -e "Please enter ${IWHITE}$MAGIC_CODE_TEST${NC} as the recovery verification code."
	docker exec redis6969 redis-cli SET magicCode $MAGIC_CODE_TEST 2>&1 > /dev/null
fi


exit 0

