#!/bin/bash

# URLs for configuration files
DOCKER_COMPOSE_URL="https://git.masscivicdynamic.com/masscivicdynamic/nexo-cloud/raw/branch/main/script/docker-compose.yml"
KUBERNETES_DEPLOY_URL="https://git.masscivicdynamic.com/masscivicdynamic/nexo-cloud/raw/branch/main/script/kubernets-deploy.yaml"
ENV_FILE="/data/nexo-cloud/.env"
DATA_DIR="/data/nexo-cloud"

# Minimum disk space requirements (in GB)
MIN_TOTAL_DISK_SPACE=30
MIN_AVAILABLE_DISK_SPACE=20

# Function to check if a command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to generate a random password
generate_random_password() {
    echo "$(openssl rand -base64 16)"
}

# Function to generate a new APP_KEY
generate_app_key() {
    echo "$(openssl rand -base64 32)"
}

# Function to check disk space requirements
check_disk_space() {
    local total_space=$(df --output=size "$DATA_DIR" | tail -n 1 | awk '{print $1}')
    local available_space=$(df --output=avail "$DATA_DIR" | tail -n 1 | awk '{print $1}')
    local total_space_gb=$((total_space / 1024 / 1024))
    local available_space_gb=$((available_space / 1024 / 1024))

    if [ "$total_space_gb" -lt "$MIN_TOTAL_DISK_SPACE" ]; then
        echo "Error: Total disk space is less than $MIN_TOTAL_DISK_SPACE GB."
        exit 1
    fi

    if [ "$available_space_gb" -lt "$MIN_AVAILABLE_DISK_SPACE" ]; then
        echo "Error: Available disk space is less than $MIN_AVAILABLE_DISK_SPACE GB."
        exit 1
    fi
}

# Function to create the folder if it doesn't exist
ensure_data_directory() {
    if [ ! -d "$DATA_DIR" ]; then
        echo "Creating directory $DATA_DIR..."
        mkdir -p "$DATA_DIR"
        echo "Directory $DATA_DIR created successfully."
    fi
}

# Function to handle the .env file
handle_env_file() {
    if [ ! -f "$ENV_FILE" ]; then
        echo "No .env file found. Creating a new one."
        touch "$ENV_FILE"
    fi

    # Generate and append variables
    APP_KEY=$(generate_app_key)
    APP_NAME="NexoCloud"
    DB_USERNAME="nexo-cloud"
    DB_PASSWORD=$(generate_random_password)
    REDIS_PASSWORD=$(generate_random_password)

    # Set APP_NAME
    if ! grep -q "^APP_NAME=" "$ENV_FILE"; then
        echo "APP_NAME=$APP_NAME" >> "$ENV_FILE"
        echo "Default APP_NAME set to $APP_NAME."
    fi

    # Handle APP_PREVIOUS_KEYS and APP_KEY
    if grep -q "^APP_KEY=" "$ENV_FILE"; then
        PREVIOUS_KEYS=$(grep "^APP_PREVIOUS_KEYS=" "$ENV_FILE" | cut -d'=' -f2)
        NEW_PREVIOUS_KEYS="${PREVIOUS_KEYS},$(grep "^APP_KEY=" "$ENV_FILE" | cut -d'=' -f2)"
        sed -i '/^APP_PREVIOUS_KEYS=/d' "$ENV_FILE"
        echo "APP_PREVIOUS_KEYS=$NEW_PREVIOUS_KEYS" >> "$ENV_FILE"
    else
        echo "APP_PREVIOUS_KEYS=$APP_KEY" >> "$ENV_FILE"
    fi
    sed -i '/^APP_KEY=/d' "$ENV_FILE"
    echo "APP_KEY=$APP_KEY" >> "$ENV_FILE"

    # Set DB_USERNAME if not present
    if ! grep -q "^DB_USERNAME=" "$ENV_FILE"; then
        echo "DB_USERNAME=$DB_USERNAME" >> "$ENV_FILE"
        echo "Default DB_USERNAME set to $DB_USERNAME."
    fi

    # Set DB_PASSWORD if not present
    if ! grep -q "^DB_PASSWORD=" "$ENV_FILE"; then
        echo "DB_PASSWORD=$DB_PASSWORD" >> "$ENV_FILE"
        echo "Generated DB_PASSWORD."
    fi

    # Set REDIS_PASSWORD if not present
    if ! grep -q "^REDIS_PASSWORD=" "$ENV_FILE"; then
        echo "REDIS_PASSWORD=$REDIS_PASSWORD" >> "$ENV_FILE"
        echo "Generated REDIS_PASSWORD."
    fi

    echo "Environment variables set up in $ENV_FILE."
}

# Function to load the .env file
load_env_file() {
    if [ -f "$ENV_FILE" ]; then
        export $(grep -v '^#' "$ENV_FILE" | xargs)
        echo "Environment variables loaded from $ENV_FILE."
    else
        echo "No .env file found. Exiting."
        exit 1
    fi
}

# Main installation logic
install_application() {
    ensure_data_directory
    check_disk_space
    handle_env_file
    load_env_file

    if command_exists docker; then
        echo "Docker detected. Proceeding with Docker setup..."
        curl -o docker-compose.yml $DOCKER_COMPOSE_URL
        echo "docker-compose.yml downloaded successfully."
        echo "Running Docker Compose with the environment variables..."
        docker-compose --env-file "$ENV_FILE" up -d
    elif command_exists kubectl || command_exists k3s; then
        echo "K3s or Kubernetes detected. Proceeding with Kubernetes setup..."
        curl -o kubernetes-deploy.yaml $KUBERNETES_DEPLOY_URL
        echo "kubernets-deploy.yaml downloaded successfully."
        echo "Applying Kubernetes deployment..."
        kubectl apply -f kubernetes-deploy.yaml
    else
        echo "Neither Docker nor Kubernetes is installed."
        read -r -p "Would you like to install Docker or K3s? (docker/k3s): " choice
        case "$choice" in
            docker)
                install_docker
                curl -o docker-compose.yml $DOCKER_COMPOSE_URL
                echo "docker-compose.yml downloaded successfully."
                echo "Running Docker Compose with the environment variables..."
                docker-compose --env-file "$ENV_FILE" up -d
                ;;
            k3s)
                install_k3s
                curl -o kubernetes-deploy.yaml $KUBERNETES_DEPLOY_URL
                echo "kubernets-deploy.yaml downloaded successfully."
                echo "Applying Kubernetes deployment..."
                kubectl apply -f kubernetes-deploy.yaml
                ;;
            *)
                echo "Invalid choice. Exiting."
                exit 1
                ;;
        esac
    fi
}

# Function to install Docker
install_docker() {
    echo "Docker is not installed. Installing Docker..."
    curl -fsSL https://get.docker.com | bash
    sudo systemctl start docker
    sudo systemctl enable docker
    echo "Docker installed successfully."
}

# Function to install K3s
install_k3s() {
    echo "K3s is not installed. Installing K3s..."
    curl -sfL https://get.k3s.io | sh -
    echo "K3s installed successfully."
}

# Run the installation process
install_application