#!/bin/bash

# Script Name: Supernote Private Cloud Install Script
# Date: 2025.09.01
# Version: v1.2
# Description: Automated installation and update of Supernote Private Cloud
set -e
# Color Definition
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Version Management Configuration
VERSION_FILE="./.supernote_versions"
LOG_FILE="./supernote_update.log"
DOCKERHUB_NAMESPACE="supernote"  # Docker Hub repository name
TARGET_SERVICES=("notelib" "supernote-service" "mariadb" "redis")  # List of Services Requiring Updates
BACKUP_DIR="./backups"

declare -A ALLOWED_COMMANDS=(
    ["apt-get"]=1
    ["yum"]=1
    ["docker"]=1
    ["docker-compose"]=1
    ["curl"]=1
    ["systemctl"]=1
    ["mkdir"]=1
    ["chmod"]=1
    ["mv"]=1
    ["cp"]=1
    ["rm"]=1
    ["sleep"]=1
    ["amazon-linux-extras"]=1
    ["add-apt-repository"]=1
    ["yum-config-manager"]=1
    ["gpg"]=1
    ["apt-key"]=1
    ["useradd"]=1
    ["usermod"]=1
    ["chown"]=1
    ["basename"]=1
    ["xargs"]=1
    ["sed"]=1
)
# Initialization Log
init_log() {
    mkdir -p "$(dirname "$LOG_FILE")"
    echo "=== Supernote Private Cloud Log $(date) ===" > "$LOG_FILE"
    chmod 600 "$LOG_FILE"
}

# Logging Function
log() {
    local level=$1
    local message=$2
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    local safe_message="$message"
    local sensitive_patterns=(
        "MYSQL_ROOT_PASSWORD="
        "MYSQL_PASSWORD="
        "REDIS_PASSWORD="
        "password="
        "secret="
        "token="
        "key="
    )
    for pattern in "${sensitive_patterns[@]}"; do
        safe_message=$(echo "$safe_message" | sed "s/${pattern}[^ ]*/${pattern}*******/g")
    done
    
    case $level in
        "ERROR") echo -e "${RED}[$timestamp] [$level] ${safe_message}${NC}" ;;
        "WARN") echo -e "${YELLOW}[$timestamp] [$level] ${safe_message}${NC}" ;;
        "INFO") echo -e "${GREEN}[$timestamp] [$level] ${safe_message}${NC}" ;;
        *) echo -e "[$timestamp] [$level] ${message}" ;;
    esac
    
    echo "[$timestamp] [$level] ${message}" >> "$LOG_FILE"
}

# Progress animation
spinner() {
    local pid=$1
    local delay=0.2
    local spinstr='|/-\'
    while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
        local temp=${spinstr#?}
        printf " [%c]  " "$spinstr"
        local spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b\b\b\b"
    done
    printf "    \b\b\b\b"
}

# Task Execution Functions with Progress Display
run_with_progress() {
    local task_name="$1"
    shift

    if [ $# -gt 0 ]; then
        local base_cmd=$(echo "$1" | awk '{print $1}' | xargs basename 2>/dev/null || echo "")
        if [[ -n "$base_cmd" ]] && [[ -z "${ALLOWED_COMMANDS[$base_cmd]}" ]]; then
            log "ERROR" "Prohibited Commands: $base_cmd (Task: $task_name)"
            echo -e "\r${RED}${task_name}...BLOCKED${NC}"
            return 1
        fi
    fi
    
    log "INFO" "Executing: $task_name"
    echo -n -e "${BLUE}${task_name}...${NC}"
    
    local cmd_array=("$@")
    "${cmd_array[@]}" >> "$LOG_FILE" 2>&1 &
    local pid=$!
    
    
    spinner $pid &
    local spinner_pid=$!
    
    
    wait $pid
    local result=$?
    
    
    kill $spinner_pid
    wait $spinner_pid 2>/dev/null
    
    
    if [ $result -eq 0 ]; then
        echo -e "\r${GREEN}${task_name}...OK${NC}"
    else
        echo -e "\r${RED}${task_name}...FAILED${NC}"
        echo -e "${YELLOW}Error output:${NC}"
        egrep -vi 'password|secret|token|key' "$LOG_FILE" | tail -n 10
        return $result
    fi
    
    return 0
}

if [[ -t 0 ]]; then
        echo -e "${GREEN}Begin the installation or update process.${NC}"
        echo -e "${YELLOW}Important Safety Notice:${NC}"
        echo -e "${YELLOW}1. This script is only supported for local execution. Any form of remote direct execution is prohibited.${NC}"
        echo -e "${YELLOW}2. Any attempt to bypass security mechanisms will result in script execution failure.${NC}"
        echo -e "${YELLOW}3. Any modification may cause script execution errors.${NC}"
        echo -e "${YELLOW}4. The above restrictions are all necessary security measures.${NC}"
else
        echo -e "\n${YELLOW}============================== Safety Warning ==============================${NC}"
        echo -e "${YELLOW}\nUnsafe execution method detected! This script prohibits direct remote execution from URLs.${NC}"
        echo ""

        echo -e "${YELLOW}Important Safety Notice:${NC}"
        echo -e "${YELLOW}1. This script is only supported for local execution. Any form of remote direct execution is prohibited.${NC}"
        echo -e "${YELLOW}2. Any attempt to bypass security mechanisms will result in script execution failure.${NC}"
        echo -e "${YELLOW}3. Any modification may cause script execution errors.${NC}"
        echo -e "${YELLOW}4. The above restrictions are all necessary security measures.${NC}"
        echo ""

        echo -e "${YELLOW}Risk Notice:${NC}"
        echo -e "${YELLOW}1. Directly executing remote scripts is vulnerable to man-in-the-middle attacks.${NC}"
        echo -e "${YELLOW}2. The transmission process may be subject to malicious tampering of script content.${NC}"
        echo -e "${YELLOW}3. The script runs with root privileges, posing a risk of complete system compromise.${NC}"
        echo ""

        echo -e "${YELLOW}Safety Operation Guidelines:${NC}"
        echo -e "${YELLOW}1. Download the script to your local:${NC}"
        echo -e "   ${YELLOW}curl -O https://supernote-private-cloud.supernote.com/cloud/install.sh${NC}"
        echo -e "${YELLOW}2. Grant execution permissions:${NC}"
        echo -e "   ${YELLOW}chmod +x install.sh${NC}"
        echo -e "${YELLOW}3. Local execution script:${NC}"
        echo -e "   ${YELLOW}./install.sh${NC}"
        echo ""
    exit 1
fi


#####################################
######### Start Installation ########
#####################################
check_install_hash() { 
    local file_name="install.sh"
    local download_url="https://supernote-private-cloud.supernote.com/cloud"
    local hash_algo="sha256"
    local hash_file="${file_name}.${hash_algo}"
    
    if [ -f "install.sh" ];then
        log "INFO" "Installation script detected. Initiating integrity verification."
        local server_hash=""
        local checksum_url="${download_url}/${hash_file}"
            if ! server_hash=$(curl -fsSL "$checksum_url" 2>/dev/null); then
                log "ERROR" "Unable to retrieve server hash file. Exiting installation."
                return 1
            fi
        server_hash=$(echo "$server_hash" | awk '{print $1}')

        sha256sum "$file_name" |awk '{print $1}'
        local actual_checksum=$(sha256sum "$file_name" | awk '{print $1}')
            if [ "$actual_checksum" != "$server_hash" ]; then
                log "ERROR" "The file may be corrupted or tampered with. Please re-download and install the script, then try again."
                return 1
            fi
        log "INFO" "Verification successful. Proceeding with the installation or update process."
    fi
}

# ========================
# install
# ========================
show_welcome() {
    clear
    colors=(${GREEN} ${CYAN} ${BLUE})
    echo -e "${colors[0]}"
    echo -e "\n${YELLOW}Welcome to the Supernote Private Cloud deployment script!${NC}\n"
    cat << "EOF"
/ ___|   _   _   _ __     ___   _ __   _ __     ___   | |_    ___ 
\___ \  | | | | | '_ \   / _ \ | '__| | '_ \   / _ \  | __|  / _ \
 ___) | | |_| | | |_) | |  __/ | |    | | | | | (_) | | |_  |  __/
|____/   \__,_| | .__/   \___| |_|    |_| |_|  \___/   \__|  \___|
                |_|             
EOF
    echo -e "${NC}"
    
    echo -ne "${colors[1]}Supernote "
    echo -ne "${colors[1]}Private Cloud "
    echo -e "${colors[1]}v1.2${NC}"
    echo ""
    echo -e "${YELLOW}Important Safety Notice:${NC}"
    echo -e "${YELLOW}1. This script is only supported for local execution. Any form of remote direct execution is prohibited.${NC}"
    echo -e "${YELLOW}2. Any attempt to bypass security mechanisms will result in script execution failure.${NC}"
    echo -e "${YELLOW}3. Any modification may cause script execution errors.${NC}"
    echo -e "${YELLOW}4. The above restrictions are all necessary security measures.${NC}"
    echo ""   
}

# Operating System Type Detection
detect_os() {
    log "INFO" "Start detecting the operating system..."

    if [ -f /etc/synoinfo.conf ]; then
        OS="synology"
        VERSION=$(grep "unique=" /etc/synoinfo.conf | cut -d '"' -f2)
        log "INFO" "Synology DSM system detected"
        return 0
    fi

    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
        VERSION=$VERSION_ID
    elif type lsb_release >/dev/null 2>&1; then
        OS=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
        VERSION=$(lsb_release -sr)
    elif [ -f /etc/redhat-release ]; then
        OS=$(cat /etc/redhat-release | cut -d ' ' -f1 | tr '[:upper:]' '[:lower:]')
        VERSION=$(cat /etc/redhat-release | grep -oE '[0-9.]+')
    else
        OS=$(uname -s)
        VERSION=$(uname -r)
    fi
    
    if [ -f /etc/system-release ]; then
        if grep -q "Amazon Linux" /etc/system-release; then
            OS="amzn"
            VERSION=$(grep -oP 'Amazon Linux \K\d+' /etc/system-release)
        fi
    fi

    
 # Standardized Operating System Name
    case $OS in
        ubuntu) OS="ubuntu" ;;
        debian) OS="debian" ;;
        rhel|redhatenterprise*) OS="rhel" ;;
        centos) OS="centos" ;;
        amzn|amazon*) OS="amzn" ;;
        synology) OS="synology";;
        *) ;;
    esac
    
    # Check supported operating systems
    case $OS in
        centos|amzn|ubuntu|debian|synology)
            log "INFO" "Supported operating systems detected"
            ;;
        *)
            log "ERROR" "Unrecognized or unsupported operating system"
            echo -e "${RED}ERROR Unsupported operating system types${NC}"
            echo -e "${YELLOW}This script supports CentOS/RHEL, Amazon Linux, Ubuntu, Debian, and Synology DSM systems.${NC}"
            exit 1
            ;;
    esac
    
    return 0
}

echo -e "\n${YELLOW}The installation process is about to begin. Please keep the deployment tool running!${NC}\n"

# Pre-installation inspection
preflight_check() {

    echo -e "\n${CYAN}======== System Environment Pre-Check ========${NC}"
    log "INFO" "Checking system requirements..."

    # check system version
    detect_os || {
        echo -e "${RED}Unable to detect operating system type${NC}"
        exit 1
    }

    # Check permission
    if [ "$(id -u)" -ne 0 ]; then
        echo -e "${RED}Error: You need to run this script as the root user.${NC}"
        exit 1
    fi

    # check disk space
    local free_space_gb=$(df -BG . | awk 'NR==2 {print $4}' | tr -d 'G')
    if [ ${free_space_gb} -lt 50 ]; then
        log "ERROR" "Insufficient disk space (Current: ${free_space_gb} GB, Minimum Requirements: 50 GB)"
        return 1
    else
        log "INFO" "Disk space check passed. Available: ${free_space_gb} GB"
    fi

    # check cpu cores
    local cpu_cores=$(nproc)
    if [ ${cpu_cores} -lt 2 ]; then
        log "ERROR" "Insufficient CPU cores (Current: ${cpu_cores}, Minimum Requirements: 2 cores)"
        return 1
    else
        log "INFO" "Passed CPU Cross-Check. Available: ${cpu_cores} cores"
    fi


    # check memory
    local mem_total=$(free -m | awk '/Mem:/ {print $2}')
    if [ ${mem_total} -lt 1500 ]; then
        log "ERROR" "Insufficient memory (Current: ${mem_total}MB, Minimum Requirements: 2GB))"
        return 1
    else
        log "INFO" "Memory check passed. Available: ${mem_total}MB"
    fi

    log "INFO" "System Environment Check Successfully"
    return 0
}

cleanup_docker_install() {
    log "INFO" "Clean up files and configurations generated during the Docker installation process"
    
    case $OS in
        ubuntu|debian)
            rm -f /etc/apt/sources.list.d/docker.list
            rm -f /etc/apt/trusted.gpg.d/docker*.gpg
            rm -f /usr/share/keyrings/docker*.gpg
            rm -f /etc/apt/keyrings/docker-aliyun.gpg
            rm -f /etc/apt/keyrings/docker.gpg
            apt-get clean
            ;;
        centos|rhel)
            rm -f /etc/yum.repos.d/docker-ce.repo
            yum clean all
            ;;
    esac
    

    if [ -d "$(pwd)/docker" ]; then
        rm -rf "$(pwd)/docker"
    fi
    
    log "INFO" "Docker cleanup complete"
}

clean_history_docker_images() {
    IMAGES=("supernote-service" "notelib")
    echo -e "\n${CYAN}======== Clean up historical image versions ========${NC}"

    for image in "${IMAGES[@]}"; do
        echo -e "\n${CYAN}======== Cleaning up historical versions of ${image} ========${NC}"


        local image_list=()
        while IFS= read -r line; do
            image_list+=("$line")
        done < <(docker images --format "{{.ID}} {{.Tag}}" "${DOCKERHUB_NAMESPACE}/${image}" | sort -k2 -V)


        local keep_count=1
        local total_images=${#image_list[@]}
        local delete_count=$((total_images - keep_count))

        if [ $delete_count -gt 0 ]; then
            echo -e "${YELLOW}Found ${total_images} versions, keeping the latest ${keep_count}, deleting ${delete_count} old versions${NC}"

            for ((i=0; i<delete_count; i++)); do
                local line="${image_list[$i]}"
                local image_id=$(echo "$line" | awk '{print $1}')
                local image_tag=$(echo "$line" | awk '{print $2}')

                echo -e "${YELLOW}Deleting old version: ${image_tag} (${image_id})${NC}"
                docker rmi "${DOCKERHUB_NAMESPACE}/${image}:${image_tag}" >/dev/null 2>&1
            done


            local remaining=$(docker images --format "{{.Tag}}" "${DOCKERHUB_NAMESPACE}/${image}" | wc -l)
            if [ "$remaining" -eq "$keep_count" ]; then
                echo -e "${GREEN}Successfully cleaned old versions. Kept latest version.${NC}"
            else
                echo -e "${RED}Warning: Some old versions could not be deleted${NC}"
            fi
        else
            echo -e "${GREEN}No old versions found for ${image}. Keeping the current version.${NC}"
        fi
    done
    echo -e "\n${GREEN}Cleanup completed${NC}"
}
verify_file_integrity() {
    local file_name=$1
    local download_url=$2
    local hash_file=$3

    local server_hash=""
    local checksum_url="${download_url}/${hash_file}"
    if ! server_hash=$(curl -fsSL "$checksum_url" 2>/dev/null); then
        log "ERROR" "Unable to retrieve the server hash file."
        return 1
    fi
    server_hash=$(echo "$server_hash" | awk '{print $1}')

    if ! run_with_progress "Download $file_name" curl -fsSL ${download_url}/${file_name} -o "$(pwd)/${file_name}"; then
        log "ERROR" "Failed to download $file_name from ${download_url}/${file_name}"
        return 1
    fi

    local actual_checksum=$(sha256sum "$file_name" | awk '{print $1}')
    if [ "$actual_checksum" != "$server_hash" ]; then
        log "ERROR" "The file may be corrupted or tampered with. Please check the file and try again."
        return 1
    fi
    return 0
}
# check network connection
check_network() {
    echo -e "\n${CYAN}======== Network Environment Detection ========${NC}"
    local test_urls=(
        "https://hub.docker.com"
        "https://www.google.com"
        "https://download.docker.com"
        "https://github.com"
    )
     
    log "INFO" "Checking network connectivity..."
     
    for url in "${test_urls[@]}"; do
        run_with_progress "Testing connection to ${url}" curl --connect-timeout 5 --max-time 10 -s --head --fail "${url}" -o /dev/null
        if [ $? -eq 0 ]; then
            log "INFO" "Network test passed (Reachable: ${url})"
            return 0
        fi
        log "WARN" "Failed to reach ${url}, trying next..."
    done
     
    log "ERROR" "All network tests failed. Please check your internet connection."
    return 1
}

# Install dependencies
install_dependencies() {
    echo -e "\n${CYAN}======== Install dependencies ========${NC}"

    log "INFO" "Check system dependencies..."

    # Synology System Special Handling
    if [ "$OS" == "synology" ]; then
        log "INFO" "Synology system detected. Skipping dependency installation"
        echo -e "${YELLOW}Synology systems come pre-installed with all necessary dependencies; skip the dependency installation step.${NC}"
        return 0
    fi


    if [[ "$OS" =~ centos ]]; then
    log "WARN" "We have detected that your system is running CentOS. As CentOS has reached its end-of-life, we recommend deploying using Ubuntu or Debian 12."
    fi

    if [ -z "$OS" ]; then
        log "ERROR" "Operating system type not detected (OS variable is empty)"
        return 1
    fi

    # Base dependency packages (required for all systems)
    local common_deps=("curl" "wget" "tar" "gzip")
    local pkg_manager=""
    local install_cmd=""
    local update_cmd=""
    local specific_deps=()
    
    # Setting specific dependencies and installation commands based on the operating system
    case $OS in
        ubuntu|debian)
            pkg_manager="apt-get"
            install_cmd="apt-get install -y"
            update_cmd="apt-get update"
            specific_deps=("software-properties-common" "apt-transport-https" "ca-certificates" "gnupg-agent")
            ;;
        rhel)
            pkg_manager="yum"
            install_cmd="yum install -y"
            update_cmd="yum update -y"
            specific_deps=("yum-utils")
            ;;
        amzn)
            pkg_manager="yum"
            install_cmd="yum install -y"
            update_cmd="yum update -y"
            specific_deps=("yum-utils")
            ;;
        centos)
            pkg_manager="yum"
            install_cmd="yum install -y"
            update_cmd="yum update -y"
            specific_deps=("yum-utils")
            
            run_with_progress "Backup the old yum repository" mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
            if [ $? -ne 0 ]; then
            log "WARN" "Backup failed. Please verify that the file exists. This step does not affect the deployment process...."
            fi
    
            run_with_progress "Add CentOS 7 repository" curl -fsSL https://supernote-private-cloud.supernote.com/cloud/CentOS-Base.repo -o /etc/yum.repos.d/CentOS-Base.repo 
            if [ $? -ne 0 ]; then
            log "WARN" "Addition failed..."
            run_with_progress "Re-add CentOS 7 Repositories" curl -fsSL http://mirrors.vmshell.com/repo/CentOS-Base.repo -o /etc/yum.repos.d/CentOS-Base.repo
            fi

            run_with_progress "Clear old cache" yum clean all 
            run_with_progress "Create cache" yum makecache
            if [ $? -ne 0 ]; then
                log "WARN" "Cache failure..."
            fi
            ;;
        *)
            log "ERROR" "Unsupported operating systems"
            return 1
            ;;
    esac

    # Update package index (required for Ubuntu/Debian only)
    if [[ "$OS" =~ (ubuntu|debian) ]]; then
        log "INFO" "Update Software Package Index..."
        run_with_progress "Update Software Package Index" $update_cmd
        [ $? -ne 0 ] && { log "ERROR" "Failed to update package index"; return 1; }
    fi

    
    # Merge all dependencies
    local all_deps=("${common_deps[@]}" "${specific_deps[@]}")
    
    # Installation of dependencies
    for pkg in "${all_deps[@]}"; do
        if ! command -v "${pkg}" &>/dev/null; then
            log "INFO" "Installation ${pkg}..."
            echo -e "\n${YELLOW}Please wait while the installer automatically initializes the installation environment.${NC}"
            run_with_progress "Installation ${pkg}" $install_cmd ${pkg}
            if [ $? -ne 0 ]; then
                log "ERROR" "Installation failed ${pkg}"
                return 1
            fi
        fi
    done

    log "INFO" "System dependency installation successful"
    return 0
}

# service helath checking
probe_service() {
    local service_name=$1
    local port=$2
    local max_attempts=300
    local attempt=0
    local wait_seconds=1
    local spin=('-' '\\' '|' '/')
    local spin_idx=0

    echo -e "\n${CYAN}Please wait ${service_name} service to start...${NC}"
    echo -n "    [Checking installation] "

    while [ $attempt -lt $max_attempts ]; do
        printf "\r    [Checking installation] ${spin[$spin_idx]}"
        spin_idx=$(( (spin_idx + 1) % 4 ))
        
        docker inspect -f '{{.State.Running}}' $service_name >/dev/null 2>&1
        if [ $? -ne 0 ]; then
            printf "\r    ${RED}✗ container not running${NC}\n"
            return 1
        fi

        docker exec $service_name /bin/sh -c \
          "timeout 1 bash -c 'echo > /dev/tcp/localhost/$port'" >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            printf "\r    ${GREEN}✓ Service ready (time: $((attempt * wait_seconds))s)${NC}\n"
            return 0
        fi

        attempt=$((attempt + 1))
        sleep 0.1
    done

    printf "\r    ${RED}✗ Start timeout try (${max_attempts}) times later${NC}\n"
    return 1
}
 
# Installing Docker
install_docker() {
    echo -e "\n${CYAN}======== Install Docker service ========${NC}"
    log "INFO" "Checking Docker installation..."
     
    if command -v docker &>/dev/null; then
        docker_version=$(docker --version | awk '{print $3}' | tr -d ',')
        log "INFO" "Docker already installed"
        return 0
    fi

    detect_os
    case $OS in 
            synology)
            log "WARN" "Synology system detected. Please install Container Manager via the DSM interface."
            echo -e "${YELLOW}Please install the Container Manager package through the ‘Package Center’ in Synology DSM.${NC}"
            echo -e "${YELLOW}1. Open the DSM management interface${NC}"
            echo -e "${YELLOW}2. Enter 'Package Center'${NC}"
            echo -e "${YELLOW}3. Search for and install Container Manager${NC}"
            echo -e "${YELLOW}4. After installation is complete, please rerun this script.${NC}"
            exit 1
            ;;
            ubuntu|debian)
            log "INFO" "Installing Docker for Ubuntu/Debian"
        
            #install dependencies
            log "INFO" "Install Docker"
            run_with_progress "Install Docker" apt-get install -y docker.io
            ;;
        centos|rhel)
            log "INFO" "Installing Docker for CentOS/RHEL"
            
            #install dependencies
            run_with_progress "Installing dependencies" yum install -y yum-utils
            
            # add repository
            run_with_progress "Adding Docker repository" yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
            if [ $? -ne 0 ]; then
                log "ERROR" "Failed to add Docker repository"
                cleanup_docker_install
                return 1
            fi

            # install docker
            run_with_progress "Installing Docker packages" yum install -y docker-ce docker-ce-cli containerd.io
            if [ $? -ne 0 ]; then
                log "ERROR" "Failed to install Docker packages"
                cleanup_docker_install
                return 1
            fi
            ;;
        amzn)
            log "INFO" "Installing Docker for Amazon Linux"
            
            # install docker
            run_with_progress "Installing Docker" amazon-linux-extras install -y docker
            ;;
            
            *)
            log "ERROR" "Unsupported operating system"
            return 1
            ;;
    esac
    if [ "$OS" != "synology" ]; then 
        log "INFO" "Configure Docker Engine"
        run_with_progress "Create Docker directory and docker data directory" mkdir -p /etc/docker
        run_with_progress "Create Docker data directory" mkdir -p "$(pwd)/docker"
        
        # Create a more secure daemon.json
        cat > /etc/docker/daemon.json << EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"data-root": "$(pwd)/docker"
}        
EOF

    [ $? -ne 0 ] && { log "ERROR" "Docker configuration failed"; return 1; }

        # Start and enable the Docker service
        run_with_progress "reload Docker Config" systemctl daemon-reload

        run_with_progress "start docker service" systemctl restart docker
        [ $? -ne 0 ] && { log "ERROR" "Failed to start the Docker service"; return 1; }

        run_with_progress "Enable Docker service" systemctl enable docker
        [ $? -ne 0 ] && { log "ERROR" "Failed to enable Docker service"; return 1; }
    fi
    log "INFO" "Successfully installed and configured Docker"
    return 0
}
 
# Check the status of the Docker service
check_docker_service() {
    echo -e "\n${CYAN}======== Check the status of the Docker service ========${NC}"

    log "INFO" "Check the status of the Docker service..."

    # Synology System Special Handling
    if [ "$OS" == "synology" ]; then
        if ! command -v docker &>/dev/null; then
            log "ERROR" "Docker service not detected. Please ensure Container Manager has been installed via Synology Package Center."
            return 1
        fi
        
        # Synology's Docker service is always running and does not require systemctl checks.
        log "INFO" "Synology system detected; skipping service status check."
        return 0
    fi
     
    run_with_progress "Check the Docker service" systemctl is-active docker
    if [ $? -ne 0 ]; then
        log "WARN" "Docker The service is not running. Attempting to start it...."
        run_with_progress "start Docker service" systemctl start docker
        [ $? -ne 0 ] && { log "ERROR" "Failed to start the Docker service"; return 1; }
    fi
     
    run_with_progress "Testing Docker" docker ps
    [ $? -ne 0 ] && { log "ERROR" "Docker Daemon process unresponsive"; return 1; }
     
    log "INFO" "Docker The service is running."
    return 0
}
 
# Installation Docker Compose
install_docker_compose() {

    local download_url="https://supernote-private-cloud.supernote.com/cloud"
    local file_name="docker-compose"
    local hash_algo="sha256"
    local hash_file="docker-compose.${hash_algo}"

    echo -e "\n${CYAN}======== Installation docker-compose ========${NC}"
    log "INFO" "Check the installation status of Docker Compose."

     
    if command -v docker-compose &>/dev/null; then
        compose_version=$(docker-compose --version | awk '{print $4}' | tr -d ',')
        log "INFO" "Docker Compose is installed. (Version: ${compose_version})"
        return 0
    fi
     
    log "INFO" "Installation Docker Compose..."
    echo -e "\n${YELLOW}Please wait, the docker-compose service is not installed. Installing the docker-compose service.${NC}"

    if [ "$OS" == "synology" ]; then
        if ! command -v docker-compose &>/dev/null; then
            log "INFO" "Docker Compose not detected. Attempting to install..."
            
            if ! verify_file_integrity "$file_name" "$download_url" "$hash_file"; then
                rm -f "$file_name"
                return 1
            fi

            mv $(pwd)/$file_name /usr/local/bin/docker-compose
            chmod +x /usr/local/bin/docker-compose
            ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
            [ $? -ne 0 ] && { log "ERROR" "docker-compose installation failed"; return 1; }
        fi
    else
        log "INFO" "Docker Compose not detected. Attempting to install..."

        if ! verify_file_integrity "$file_name" "$download_url" "$hash_file"; then
            rm -f "$file_name"
            return 1
        fi
        
        mv $(pwd)/$file_name /usr/local/bin/docker-compose
        chmod +x /usr/local/bin/docker-compose
        ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
        [ $? -ne 0 ] && { log "ERROR" "docker-compose Installation failed"; return 1; }
    fi
    
    log "INFO" "Docker Compose installation successful"
    return 0
}

# Generate database password
generate_db_credentials() {
    if [ -f ".dbenv" ]; then
        log "INFO" "An environment variable file has been detected; the existing configuration will be used."
        local perms=$(stat -c %a .dbenv 2>/dev/null || stat -f %A .dbenv 2>/dev/null)
        if [ "$perms" != "600" ]; then
            chmod 600 .dbenv
            log "WARN" "The permissions for the .dbenv file have been corrected to 600."
        fi
        source .dbenv
    else
        log "INFO" "Generate new database credentials"
        
        MYSQL_ROOT_PASSWORD=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 16)
        MYSQL_PASSWORD=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 12)
        REDIS_PASSWORD=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c 12)
        MYSQL_DATABASE="supernotedb"
        MYSQL_USER="enote"
        
        cat > .dbenv <<EOF
# Auto-generated database credentials
MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
MYSQL_PASSWORD=$MYSQL_PASSWORD
REDIS_PASSWORD=$REDIS_PASSWORD
MYSQL_DATABASE=$MYSQL_DATABASE
MYSQL_USER=$MYSQL_USER
EOF
        
        chmod 600 .dbenv
        log "INFO" "New database credentials have been generated."
    fi
    
    export MYSQL_ROOT_PASSWORD MYSQL_PASSWORD MYSQL_DATABASE MYSQL_USER REDIS_PASSWORD
}

init_database() {
    local file_name="supernotedb.sql"
    local DB_CONTAINER="mariadb"
    local download_url="https://supernote-private-cloud.supernote.com/cloud"
    local hash_algo="sha256"
    local hash_file="supernotedb.sql.${hash_algo}"
    echo -e "\n${CYAN}======== Update the database ========${NC}"
    if ! verify_file_integrity "$file_name" "$download_url" "$hash_file"; then
        rm -f "$file_name"
        return 1
    fi

    echo -e "\n${CYAN}Import database structure...${NC}"
    docker exec -i "$DB_CONTAINER" mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" < "$file_name"
    if [ $? -eq 0 ]; then
        log "INFO" "Database initialization completed successfully."
        
        local required_tables=( "b_dictionary" "e_task" "f_capacity")
        for table in "${required_tables[@]}"; do
            if ! docker exec "$DB_CONTAINER" mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" -e "DESCRIBE "$table"" &>/dev/null; then
                log "ERROR" "Failed to initialize the key table $table"
                return 1
            fi
        done
        
        echo -e "${GREEN}✓ Database verification passed${NC}"
        return 0
    else
        log "ERROR" "Database initialization failed"
        return 1
    fi
}

#View System Information
system_summary() {
    echo -e "${YELLOW}Installation Summary:${NC}"
    echo -e "- Docker Version: $(docker --version | awk '{print $3}' | tr -d ',')"
    echo -e "- Docker Compose Version: $(docker-compose --version | awk '{print $4}' | tr -d ',')"
    echo -e "- Available Disk Space: $(df -h . | awk 'NR==2 {print $4}')"
    echo -e "- Network Connectivity: OK"
}
 
# Installation Supernote Private Cloud
deploy_supernote_cloud() {
    echo -e "\n${CYAN}======== Deploy Supernote Private Cloud Services ========${NC}"

    local base_dir="./sndata"
    local dirs=(
    "${base_dir}/db_data"                # Database Data Directory
    "${base_dir}/config/mysql/conf.d"    # MySQL Configuration File Directory
    "${base_dir}/redis_data"             # Redis Data Directory
    "${base_dir}/recycle"                # Recycle Bin Directory
    "$(pwd)/supernote_data"              # Supernote Master Data Catalog
    "${base_dir}/logs/cloud"             # Cloud Service Log Directory
    "${base_dir}/logs/app"               # Application Log Directory
    "${base_dir}/logs/web"               # Web Service Logs
    "${base_dir}/logs/notelib"           # notelib Service Log
    "${base_dir}/convert"                # Note Conversion File
    "$(pwd)/${BACKUP_DIR}"
    )
    local file_name="docker-compose.yml"
    local download_url="https://supernote-private-cloud.supernote.com/cloud"
    local hash_algo="sha256"
    local hash_file="docker-compose.yml.${hash_algo}"
 
        for dir in "${dirs[@]}"; do
            if [ ! -d "$dir" ]; then
                mkdir -p "$dir" || {
                log "ERROR" "Unable to create directory: $dir"
                return 1
            }
        chmod 755 "$dir"
        log "INFO" "The directory has been created: $dir"
    fi
    done

    generate_db_credentials
    # check docker-compose file

    if ! verify_file_integrity "$file_name" "$download_url" "$hash_file"; then
        rm -f "$file_name"
        return 1
    fi

 
    # check docker-compose config
    run_with_progress "Verification  docker-compose Configuration" docker-compose config
    [ $? -ne 0 ] && { log "ERROR" "docker-compose Configuration is invalid."; return 1; }


    # start service
    log "INFO" "Start Supernote Private Cloud Service..."
    if docker-compose up -d; then
        # check service status
        local status=$(docker-compose ps | grep -v "Name" | awk '{print $4}')
        
        echo -e "\n${GREEN}=== Deployment successful ===${NC}"
        echo -e "Service Status:"
        docker-compose ps | tail -n +2

        # Synology Special Notice
        if [ "$OS" == "synology" ]; then
            echo -e "\n${YELLOW}Attention Synology Users:${NC}"
            echo -e "1. You can manage these containers through Synology's Container Manager interface."
            echo -e "2. It is recommended to set these containers to start automatically in the Synology Control Panel."
            echo -e "3. Data Directory: $(pwd)/supernote_data"
        fi
        return 0
    else
        log "ERROR" "Failed to start the service"
        echo -e "${RED}Error: Service startup failed${NC}"
        
        # Trying to get the error log
        local err_containers=$(docker-compose ps | grep -v "Name" | grep "Exit" | awk '{print $1}')
        for container in $err_containers; do
            echo -e "\n${YELLOW}container $container logs:${NC}"
            docker logs "$container" | tail -n 10
        done
        
        return 1
    fi
}

# Display deployment completion information
show_success_info() {
    if [ "$OS" != "synology" ]; then
    local ip_address=$(hostname -I | awk '{print $1}')
    fi
    local install_dir=$(pwd)
    local nas_address
    nas_address=$(
        ip -o -4 addr show scope global | awk '{print $4}' | cut -d'/' -f1 2>/dev/null |
        grep -v '^127.' | head -n1
    
        [ $? -ne 0 ] && hostname -I 2>/dev/null | awk '{print $1}'
    )
    
    if [ -z "$nas_address" ] || [[ "$nas_address" == "127."* ]]; then
        nas_address=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | 
                     grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n1)
    fi

     
    echo -e "\n${YELLOW}All programs are initializing. Please wait.${NC}"
     
    echo -n -e "${BLUE}Initialize Service...${NC}"
    probe_service "mariadb" "3306" || return 1
    if ! init_database; then
    log "ERROR" "Database initialization failed. Terminate script execution and exit the installation or update process."
    exit 1
    fi

    probe_service "redis" "6379" || return 1

    probe_service "notelib" "6000" || return 1

    probe_service "supernote-service" "19071" || return 1
    echo -e "\n${GREEN}backend service ${NC}" 

    probe_service "supernote-service" "8080" || return 1
    echo -e "\n${GREEN}web service ${NC}" 

    probe_service "supernote-service" "9888" || return 1
    echo -e "\n${GREEN}frontend service ${NC}"


    if [ "$OS" == "synology" ]; then
        echo -e "\n${GREEN}==========================================================================${NC}"
        echo -e "${GREEN}       Successfully Installed Supernote Private Cloud on Synology NAS       ${NC}"
        echo -e "${GREEN}============================================================================${NC}"
        echo -e "Supernote Cloud Web Access Address: ${YELLOW}http://${nas_address}:19072${NC}"
        echo -e "Installation directory: ${YELLOW}$install_dir${NC}"
        echo -e "File Data Directory: ${YELLOW}$install_dir/supernote_data/${NC}"
        echo -e "Log Directory: ${YELLOW}$install_dir/sndata/logs${NC}"
        
        echo -e "\n${YELLOW}Synology Management Notice:${NC}"
        echo -e "1. You can manage these containers using Synology's ‘Container Manager’ application."
        echo -e "2. We recommend enabling auto-start in the ‘Container’ settings."
        echo -e "3. To back up your data, please back up the entire $install_dir/supernote_data/ directory."
        
        echo -e "\n${GREEN}Use the following commands to manage services:${NC}"
        echo -e "Help Information: ${YELLOW}cd $install_dir && ./install.sh -h${NC}"
        echo -e "Start the service: ${YELLOW}cd $install_dir && docker-compose up -d${NC}"
        echo -e "Stop the service: ${YELLOW}cd $install_dir && docker-compose stop servicename${NC}"
        echo -e "View Logs: cd ${YELLOW}$install_dir && docker-compose logs${NC}"
        echo -e "Update System: ${YELLOW}cd $install_dir && ./install.sh --update${NC}"
        echo -e "${GREEN}===============================================${NC}\n"
    else
        echo -e "\n${GREEN}==========================================================${NC}"
        echo -e "${GREEN}       Successfully installed Supernote Private Cloud       ${NC}"
        echo -e "${GREEN}============================================================${NC}"
        echo -e "Supernote Cloud Web Access Address: ${YELLOW}http://$ip_address:19072${NC}"
        echo -e "Installation directory: ${YELLOW}$install_dir${NC}"
        echo -e "File Data Directory: ${YELLOW}$install_dir/supernote_data/${NC}"
        echo -e "Log Directory:  ${YELLOW}$install_dir/sndata/logs${NC}"
    fi
    
        echo -e "\n${GREEN}Use the following commands to manage services:${NC}"
        echo -e "Help Information: ${YELLOW}cd $install_dir && ./install.sh -h${NC}"
        echo -e "Start the service: ${YELLOW}cd $install_dir && docker-compose up -d${NC}"
        echo -e "Stop the service: ${YELLOW}cd $install_dir && docker-compose stop ${service}${NC}"
        echo -e "View Logs: ${YELLOW}cd $install_dir && docker-compose logs${NC}"
        echo -e "Update System: ${YELLOW}cd $install_dir && ./install.sh --update${NC}"
        echo -e "${GREEN}===============================================${NC}\n"
}

get_current_version() {
    local service=$1
    docker inspect --format '{{.Config.Image}}' "$service" 2>/dev/null | cut -d':' -f2 || echo "unknown"
}

get_latest_version() {
    local service=$1
    local retries=3
    local delay=2
    local latest_tag="unknown"

    for i in $(seq 1 $retries); do
        latest_tag=$(curl -s --fail "https://hub.docker.com/v2/repositories/${DOCKERHUB_NAMESPACE}/${service}/tags/?page_size=50" 2>/dev/null \
            | jq -r '.results[] | select(.name | test("^v?[0-9]+\\.[0-9]+\\.[0-9]+$")) | .name' 2>/dev/null \
            | sort -V | tail -n 1)

        [ -n "$latest_tag" ] && break

        latest_tag=$(curl -s --fail "https://registry.hub.docker.com/v1/repositories/${DOCKERHUB_NAMESPACE}/${service}/tags" 2>/dev/null \
            | jq -r '.[].name' 2>/dev/null \
            | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' \
            | sort -V | tail -n 1)

        [ -n "$latest_tag" ] && break

        sleep $delay
    done

    echo "${latest_tag:-unknown}"
}

init_version_file() {
    if [ ! -f "$VERSION_FILE" ]; then
        declare -A versions
        for service in "${TARGET_SERVICES[@]}"; do
            versions[$service]=$(get_current_version "$service")
            [ "${versions[$service]}" = "unknown" ] && versions[$service]="v1.0.0"
        done
        declare -p versions > "$VERSION_FILE"
    fi
}

check_updates() {
    init_version_file
    source "$VERSION_FILE" 2>/dev/null || return 1

    echo -e "\n${BLUE}=== Renewable Service Check ===${NC}"
    local update_available=0

    for service in "${TARGET_SERVICES[@]}"; do
        local current="${versions[$service]}"
        local latest=$(get_latest_version "$service")

        printf "%-20s: Currently=%-10s Latest=%-10s" "$service" "$current" "$latest"
        if [ "$latest" = "unknown" ]; then
            echo -e "  ${RED}[Version retrieval failed]${NC}"
        elif [ "$current" = "$latest" ]; then
            echo -e "  ${GREEN}[This is the latest version.]${NC}"
        else
            echo -e "  ${YELLOW}[Renewable]${NC}"
            update_available=1
        fi
    done

    return $update_available
}

update_services() {
    log "INFO" "Initiate the update process for the target services: ${TARGET_SERVICES[*]}"
    log "INFO" "Begin verifying the integrity of the installation script...."
    if ! check_install_hash; then
        log "ERROR" "Installation script integrity verification failed. Unable to proceed with the update. Please re-download and install the script."
        echo ""
        echo -e "${YELLOW}Safety Operation Guidelines:${NC}"
        echo -e "${YELLOW}1. Download the script to your local:${NC}"
        echo -e "   ${YELLOW}curl -O https://supernote-private-cloud.supernote.com/cloud/install.sh${NC}"
        echo -e "${YELLOW}2. Grant execution permissions:${NC}"
        echo -e "   ${YELLOW}chmod +x install.sh${NC}"
        echo -e "${YELLOW}3. Local execution script:${NC}"
        echo -e "   ${YELLOW}./install.sh${NC}"
        return 1
    fi

    init_version_file
    check_updates
    source "$VERSION_FILE" 2>/dev/null || return 1
    
    echo -e "\n${CYAN}======= Service Update Begins =======${NC}"
    local success=0

        
    local hash_algo="sha256"
    local hash_file="docker-compose.yml.${hash_algo}"

    if ! docker-compose config -q >/dev/null 2>&1; then
        log "ERROR" "docker-compose.yml Format error. Please check the file."
        return 1
    fi


        log "INFO" "Update database table structure"
        generate_db_credentials
        if ! init_database; then
        log "ERROR" "Database initialization failed. Terminate script execution and exit the installation or update process."
        exit 1
        fi
        local db_updated=false
        
    # NAS Update
    if [ -f /etc/synoinfo.conf ] || [ -n "$(uname -a | grep synology)" ]; then
        log "INFO" "Detected running environment: Synology NAS. Using simplified update process."
        echo -e "\n${CYAN}======= Synology NAS Environment Check =======${NC}"
        local download_url="https://supernote-private-cloud.supernote.com/cloud"
        local compose_file="docker-compose.yml"
        local tmp_compose_file="${compose_file}.tmp"
        local server_hash=""
        local checksum_url="${download_url}/${hash_file}"
            if ! server_hash=$(curl -fsSL "$checksum_url" 2>/dev/null); then
                log "ERROR" "Unable to retrieve the server hash file ${checksum_url}"
                return 1
            fi
        server_hash=$(echo "$server_hash" | awk '{print $1}')

        if ! run_with_progress "Download the Docker configuration file" curl -o $(pwd)/${tmp_compose_file} ${download_url}/${compose_file}; then
            log "ERROR" "Profile download failed. Please check your network connection."
            return 1
        fi

        local actual_checksum=$(sha256sum "$tmp_compose_file" | awk '{print $1}')
            if [ "$actual_checksum" != "$server_hash" ]; then
                log "ERROR" "Profile validation failed. The file may be corrupted or tampered with."
                rm -f "$tmp_compose_file"
                return 1
            fi

        mkdir -p "$BACKUP_DIR"
        chmod 700 $BACKUP_DIR
        local backup_file="${BACKUP_DIR}/docker-compose-$(date +%Y%m%d%H%M%S).yml"
        mv docker-compose.yml "$backup_file"
        mv "$tmp_compose_file" docker-compose.yml
        log "INFO" "Profile backup successful: $backup_file"
        log "INFO" "Profile update successful. Backup path:: $backup_file"


        if ! docker-compose -f docker-compose.yml config -q >/dev/null 2>&1; then
            log "ERROR" "Configuration verification failed after update"
            continue
        fi

        if ! run_with_progress "Stop legacy containers" "docker-compose down"; then
            log "ERROR" "Service stop failed. Please check the logs."
            return 1
        fi
        if ! run_with_progress "Launch the new version container" "docker-compose up -d"; then
            log "ERROR" "Startup failed. Please check the log."
            return 1
        fi
        if ! clean_history_docker_images; then
                exit 1
        fi
        echo -e "${GREEN}Synology NAS service started successfully.${NC}"
        return 0
    fi
    for service in "${TARGET_SERVICES[@]}"; do
        local current="${versions[$service]}"
        local latest=$(get_latest_version "$service")
        local download_url="https://supernote-private-cloud.supernote.com/cloud"
        local compose_file="docker-compose.yml"
        local tmp_compose_file="docker-compose.yml.tmp"
        
        if [ "$current" != "$latest" ] && [ "$latest" != "unknown" ]; then
            echo -e "\n${YELLOW}>>> Update ${service} (${current} → ${latest}) <<<${NC}"


            local server_hash=""
            local checksum_url="${download_url}/${hash_file}"
            if ! server_hash=$(curl -fsSL "$checksum_url" 2>/dev/null); then
                log "ERROR" "Unable to retrieve the server hash file ${checksum_url}"
                continue
            fi
            server_hash=$(echo "$server_hash" | awk '{print $1}')


            if ! run_with_progress "Download the latest version of the deployment files" curl -fsSL  ${download_url}/${compose_file} -o $(pwd)/${tmp_compose_file}; then
                log "ERROR" "${compose_file} Deployment file download failed. Please verify your network connection."
                return 1
            fi


            local actual_checksum=$(sha256sum "$tmp_compose_file" | awk '{print $1}')
            if [ "$actual_checksum" != "$server_hash" ]; then
                log "ERROR" "Profile validation failed. The file may be corrupted or tampered with."
                rm -f "$tmp_compose_file"
                return 1
            fi

            mkdir -p "$BACKUP_DIR"
            chmod 700 $BACKUP_DIR
            local backup_file="${BACKUP_DIR}/docker-compose-$(date +%Y%m%d%H%M%S).yml"
            mv docker-compose.yml "$backup_file"
            mv "$tmp_compose_file" docker-compose.yml
            log "INFO" "Profile backup successful: $backup_file"
            log "INFO" "Profile update successful. Backup path:: $backup_file"

            
            if ! docker-compose -f docker-compose.yml config -q >/dev/null 2>&1; then
                log "ERROR" "Configuration verification failed after update"
                return 1
            fi
           
            local retry=3
            while [ $retry -gt 0 ]; do
                if run_with_progress "Restart the service" docker-compose up -d $service; then
                    versions[$service]="$latest"
                    ((success++))

                     case "$service" in
                        "notelib") probe_port=6000 ;;
                        "supernote-service") probe_port=19071 ;;
                        "mariadb") probe_port=3306 ;;
                        "redis") probe_port=6379 ;;
                        *) probe_port= ;;
                    esac
                    
                    if [ -n "$probe_port" ]; then
                        if ! probe_service "$service" "$probe_port"; then
                            log "ERROR" "${service} Health check failed"
                            ((success--))
                            break
                        fi
                    fi
                    log "INFO" "${service} Update successful"
                    break
                else
                    ((retry--))
                    if [ $retry -eq 0 ]; then
                        log "ERROR" "${service} Restart failed, rolling back...."
                        run_with_progress "Restore Backup Configuration" cp "$backup_file" docker-compose.yml
                        run_with_progress "Restart all services" docker-compose restart "$service"
                    else
                        log "WARN" "${service} Restart failed. Remaining retry attempts: $retry"
                        sleep 2
                    fi
                fi
            done
        else
            log "INFO" "${service} This is the latest version; skip the update."
            ((success++))
        fi
    done


    declare -p versions > "$VERSION_FILE"
    
    echo -e "\n${CYAN}======= Update Results =======${NC}"
    if [ $success -eq ${#TARGET_SERVICES[@]} ]; then
        echo -e "${GREEN}All services have been successfully updated.${NC}"
            if ! clean_history_docker_images; then
                exit 1
            fi
        return 0
    else
        echo -e "${YELLOW}Some service updates failed. Please check the logs.${NC}"
        echo -e "For detailed logs, please refer to: ${YELLOW}$LOG_FILE${NC}"
        return 1
    fi
}

# Script Management
show_usage() {
    echo -e "\n${BLUE}Supernote Private Cloud Management Script${NC}"
    echo -e "Version: v1.2"
    echo -e "\nInstructions for Use:"
    echo -e "  $0 [Options]"
    echo -e "\nOptions:"
    echo -e "  No parameters                                        Perform the complete installation process"
    echo -e "  -u, --update                                         Update all services"
    echo -e "  -h, --help                                           Display help information"
    echo -e "  -c, --check                                          Check for the latest version"
}


# Primary Installation Functions
perform_installation() {
    echo -e "\n${GREEN}=== Supernote Private Cloud Installation ===${NC}\n"

    show_welcome
    init_log
    if ! check_install_hash; then
        echo -e "${YELLOW}Safety Operation Guidelines:${NC}"
        echo -e "${YELLOW}1. Download the script to your local:${NC}"
        echo -e "   ${YELLOW}curl -O https://supernote-private-cloud.supernote.com/cloud/install.sh${NC}"
        echo -e "${YELLOW}2. Grant execution permissions:${NC}"
        echo -e "   ${YELLOW}chmod +x install.sh${NC}"
        echo -e "${YELLOW}3. Local execution script:${NC}"
        echo -e "   ${YELLOW}./install.sh${NC}"
        exit 1
    fi


    if ! check_network; then
        exit 1
    fi
     

    if ! preflight_check; then
        exit 1
    fi
     

    if ! install_dependencies; then
        exit 1
    fi
     

    if ! install_docker; then
        exit 1
    fi
     

    if ! check_docker_service; then
        exit 1
    fi
     

    if ! install_docker_compose; then
        exit 1
    fi
     
    log "INFO" "All prerequisites have been successfully installed."
    echo -e "\n${GREEN}=== Supernote private cloud Deployment ===${NC}\n"
     

    system_summary
     

    if deploy_supernote_cloud;then
        show_success_info
    else {
        echo -e "\n${RED}Supernote Private Cloud Deployment failed. Check the logs for details..${NC}"
        exit 1
    }
    fi
    init_version_file
}


main() {
    # Ensure that parameters are passed correctly
    local command="$1"
    shift  # Remove processed parameters

    case "$command" in
        "--check-update"|"-c")
            check_updates
            return 0
            ;;
        "--update"|"-u")
                read -p "Confirm updates for all services? [y/N] " confirm
                if [[ "$confirm" =~ ^[yY] ]]; then
                    update_services
                    return $?
                else
                    echo -e "${YELLOW}Updates have been canceled.${NC}"
                    return 0
                fi
            ;;
        "--help"|"-h")
            show_usage
            return 0
            ;;
        "")
            # Execute installation without parameters
            perform_installation
            return $?
            ;;
        *)
            echo -e "${RED}Error: Unknown parameter '$command'${NC}"
            show_usage
            return 1
            ;;
    esac
}

# ========================
# Script Execution Portal
# ========================
if [[ "$0" == "$BASH_SOURCE" ]]; then
    # Ensure that the log directory exists
    mkdir -p "$(dirname "$LOG_FILE")"
    
    # Execute the main function and handle the exit status
    if main "$@"; then
        if [ "$1" == "" ]; then
            # The success message is only displayed when installing without parameters
            show_success_info
        fi
        exit 0
    else
        exit 1
    fi
fi