#!/usr/bin/env	bash
# author: Edison Y
# PATH设置

export PATH=/sbin:/bin:/usr/sbin:/usr/bin

export packagepath=$PWD

export logpath=/tmp

# 定义错误退出码
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
readonly EXIT_INVALID_PARAM=2
readonly EXIT_NO_ROOT=3
readonly EXIT_DISK_FULL=4
readonly EXIT_PORT_USED=5

# 定义颜色变量
red='\033[0;31m'
yellow='\033[1;33m'
blue='\033[0;34m'
green='\033[0;32m'
pink='\E[1;35m'
NC='\033[0m' # No Color

# 彩色文字输出函数
log_message() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $*" >> "$logpath/install.log"
}

echoColor()
{
    # 循环读取参数
    for ((i=1; i<=$#; i+=2)); do
        color=${!i}
        content=$(($i + 1))
        echo -e -n "${!color}${!content}${NC} "
    done
    echo;
}

printDHR() 
{
	echoColor pink "Start" blue "deploying" red "DHR"	yellow "services" pink ">>>>>>"
	sleep 1
	echoColor red "   ___   " yellow "  _  _  " green "  ___  "
	echoColor red "  |   \  " yellow " | || | " green " | _ \ "
	echoColor red "  | |) | " yellow " | __ | " green " |   / "
	echoColor red "  |___/  " yellow " |_||_| " green " |_|_\ "
	sleep 1
	echoColor pink "Shell" green "script"  red "disigned" yellow "by" blue "EdisonY"
}

printDHR

#三个服务进程状态判断函数
pidCheck() {
	Tomcat="dhr.war"
	PGSQL="postgres"
	MongoDB="mongod"
	#这里判断传入的参数是否不等于 1 个
	if [ $# -ne 1 ];then
		echo "Usage $0 content {tomcat|postgres|mongod}"
		exit 1
	fi

	case "$1" in
	tomcat|TOMCAT)
			count=`ps -ef | grep $Tomcat | grep -v grep | wc -l`
			if [[ $count == 0 ]];then
				echoColor green "$Tomcat process not exist"
				return 1
			else
				echoColor red "$Tomcat process exist"
			fi
			;;
	postgres|POSTGRES)
			count=`ps -ef | grep $PGSQL | grep -v grep | wc -l`
			if [[ $count == 0 ]];then
				echoColor green "$PGSQL process not exist"
				return 1
			else
				echoColor red "$PGSQL process exist"
			fi
			;;
	mongod|MONGOD)
			count=`ps -ef | grep $MongoDB | grep -v grep | wc -l`
			if [[ $count == 0 ]];then
				echoColor green "$MongoDB process not exist"
				return 1
			else
				echoColor red "$MongoDB process exist"
			fi
			;;
			*)
			echo -e "请输入指定的服务名称：{tomcat|postgres|mongod}"
	esac
}

# 输入一个路径,将输入路径赋值给dbpath变量
dbPathInput() {
    while true; do
        echo "请输入数据库服务安装目录(绝对路径):"
        read DBpath
        
        # 检查是否为绝对路径
        if [[ "$DBpath" != /* ]]; then
            echoColor red "错误: 请输入绝对路径,例如 /usr/local"
            continue
        fi
        
        # 去除末尾的 /
        DBpath=${DBpath%/}
        
        # 确认路径
        echo "请确认数据库服务安装目录: $DBpath (y/n)"
        read choose
        case "$choose" in
            Y|y)
                echoColor green "数据库服务将被安装到: $DBpath"
                echo "$DBpath" > /tmp/dbpath.txt
                return 0
                ;;
            N|n)
                echoColor yellow "请重新输入数据库服务安装路径"
                continue
                ;;
            *)
                echoColor red "请输入正确的选项(y/n)"
                continue
                ;;
        esac
    done
}

#检查服务器 CPU 架构和 AVX 指令集支持情况
checkCPUArchAndAVX() {
    echoColor green "开始检查 CPU 架构和指令集支持......"
    
    # 获取 CPU 架构
    CPU_ARCH=$(uname -m)
    
    echoColor blue "检测到 CPU 架构：$CPU_ARCH"
    
    # 判断 CPU 架构类型 安装 MongoDB
    case "$CPU_ARCH" in
        x86_64|i386|i686)
            echoColor yellow "检测到 x86/x64 架构，需要检查 AVX 指令集支持"
            # 检查是否支持 AVX 指令集
            if ! grep -q avx /proc/cpuinfo; then
                echoColor red "错误：x86/x64 架构 CPU 不支持 AVX 指令集，无法继续安装"
                echoColor red "请确认服务器硬件配置或联系系统管理员"
                exit $EXIT_FAILURE
            else
                echoColor green "CPU 支持 AVX 指令集，检查通过 安装 MongoDB 8"  >> "$logpath/install.log"
                log_message "Installing MongoDB 8 for x86_64 with AVX support"
            fi
            ;;
        aarch64|armv7l|armv6l)
            echoColor green "检测到 ARM 架构 ($CPU_ARCH)，跳过 AVX 指令集检查"
            log_message "ARM architecture detected: $CPU_ARCH"
            ;;
        *)
            echoColor red "错误：未识别的 CPU 架构：$CPU_ARCH"
            echoColor red "本系统仅支持 x86/x64 和 ARM 架构服务器"
            log_message "ERROR: Unsupported CPU architecture: $CPU_ARCH"
            exit $EXIT_FAILURE
            ;;
    esac
    
    sleep 1
}

#修改 mongodb8 预置脚本路径变量
sedMongodb8path() {
    local escaped_dbpath=$(printf '%s\n' "$dbpath" | sed 's/[&/\\]/\\&/g')
    
    sed -i "s#/usr/local#${escaped_dbpath}#g" "$dbpath/ehr/mongodb8/startmongodb.sh"
    sed -i "s#/usr/local#${escaped_dbpath}#g" "$dbpath/ehr/mongodb8/startmongodb2.sh"
    sed -i "s#/usr/local#${escaped_dbpath}#g" "$dbpath/ehr/mongodb8/stopmongodb.sh"
    sed -i "s#/usr/local#${escaped_dbpath}#g" "$dbpath/ehr/mongodb8/mongodb_data_bak.sh"
    sed -i "s#/usr/local#${escaped_dbpath}#g" "$dbpath/ehr/mongodb8/bin/mongod.cfg"
    sed -i "s#/usr/local#${escaped_dbpath}#g" "$dbpath/ehr/mongodb8/bin/mongod2.cfg"
    
    log_message "Updated MongoDB 8 scripts with path: $dbpath"
}

# 安装 MongoDB 8（x86_64 架构）
installMongoDB8_x86() {
    echoColor green "开始安装 MongoDB 8 (x86_64 架构)......"
    log_message "Installing MongoDB 8 for x86_64"
    
    # 检查安装包是否存在
    if ! ls "$packagepath"/*mongodb-8*.tar.gz 1> /dev/null 2>&1; then
        echoColor red "错误：未找到 MongoDB 8 安装包"
        echoColor yellow "提示：请确保安装包文件名包含 'mongodb-8'"
        log_message "ERROR: MongoDB 8 package not found"
        exit $EXIT_FAILURE
    fi
    
    # 解压安装包
    tar xf "$packagepath"/*mongodb-8*.tar.gz -C "$dbpath/ehr" || {
        echoColor red "错误：MongoDB 8 解压失败"
        log_message "ERROR: Failed to extract MongoDB 8"
        exit $EXIT_FAILURE
    }
    
    # 更新脚本路径
    mv "$packagepath/inti_MongoDB_index.js" "$packagepath/init_MongoDB_App.js" "$dbpath/ehr" >> "$logpath/install.log" 2>&1
    sedMongodb8path
    
    # 启动 MongoDB
    ulimit -n 65535 -u 65535
    sh "$dbpath/ehr/mongodb8/startmongodb.sh" >> "$logpath/install.log" 2>&1 || {
        echoColor red "错误：MongoDB 8 启动失败"
        log_message "ERROR: Failed to start MongoDB 8"
        exit $EXIT_FAILURE
    }
    
    # 检查 MongoDB 是否正常启动
    sleep 5
    mongo_count=$(ps -ef | grep mongod | grep mongodb8 | grep -v grep | wc -l)
    if [ "$mongo_count" -eq 0 ]; then
        echoColor red "错误：MongoDB 8 未能正常启动"
        echoColor yellow "正在查看日志文件：$dbpath/ehr/mongodb8/logs/mongodb.log"
        echoColor red "========== 日志内容开始 =========="
        if [ -f "$dbpath/ehr/mongodb8/logs/mongodb.log" ]; then
            cat "$dbpath/ehr/mongodb8/logs/mongodb.log"
        else
            echoColor red "日志文件不存在：$dbpath/ehr/mongodb8/logs/mongodb.log"
        fi
        echoColor red "========== 日志内容结束 =========="
        log_message "ERROR: MongoDB 8 failed to start. Check mongodb.log for details"
        exit $EXIT_FAILURE
    fi
    
    # 初始化数据库, 预置mongosh在mongodb8包中，不能使用command方法去判断是否存在mongosh二进制文件，如何获取预置脚本？操作文档步骤中先执行下载预置脚本
    if [ -f $dbpath/ehr/mongodb8/mongosh/bin/mongosh ]; then
        $dbpath/ehr/mongodb8/mongosh/bin/mongosh 127.0.0.1:27011/ehr -u ehr -p kh5MCLQRhe "$dbpath/ehr/inti_MongoDB_index.js" >> "$logpath/install.log" 2>&1
        $dbpath/ehr/mongodb8/mongosh/bin/mongosh 127.0.0.1:27011/ehr -u ehr -p kh5MCLQRhe "$dbpath/ehr/init_MongoDB_App.js" >> "$logpath/install.log" 2>&1
    else
        echoColor yellow "警告：mongosh 命令不存在，跳过数据库初始化"
        log_message "WARNING: mongosh command not found, skipped database initialization"
    fi
    
    echoColor green "已成功安装并启动 MongoDB 8，安装路径为 $dbpath/ehr/mongodb8"
    log_message "MongoDB 8 installed and started successfully"
}

# 安装 MongoDB 8（ARM 架构）
installMongoDB8_ARM() {
    echoColor green "检测到 ARM 架构 ($CPU_ARCH)，跳过 AVX 指令集检查"
    log_message "ARM architecture detected: $CPU_ARCH"
    
    # 检查安装包是否为 aarch 版本
    if ls "$packagepath"/*mongodb*aarch* 1> /dev/null 2>&1 || ls "$packagepath"/*MongoDB*aarch* 1> /dev/null 2>&1; then
        echoColor green "检测到适用于 ARM 架构的 MongoDB 安装包 (包含 aarch 标识) 安装 MongoDB 8" >> "$logpath/install.log"
        log_message "Found ARM-compatible MongoDB 8 package"
        
        tar xf "$packagepath"/*mongodb*aarch*.tar.gz -C "$dbpath/ehr" || {
            echoColor red "错误：MongoDB 8 解压失败"
            log_message "ERROR: Failed to extract MongoDB 8 ARM package"
            exit $EXIT_FAILURE
        }
        
        # 更新脚本路径
        mv "$packagepath/inti_MongoDB_index.js" "$packagepath/init_MongoDB_App.js" "$dbpath/ehr" >> "$logpath/install.log" 2>&1
        sedMongodb8path
        
        # 启动 MongoDB
        ulimit -n 65535 -u 65535
        sh "$dbpath/ehr/mongodb8/startmongodb.sh" >> "$logpath/install.log" 2>&1 || {
            echoColor red "错误：MongoDB 8 启动失败"
            log_message "ERROR: Failed to start MongoDB 8"
            exit $EXIT_FAILURE
        }
        
        # 检查 MongoDB 是否正常启动
        sleep 5
        mongo_count=$(ps -ef | grep mongod | grep mongodb8 | grep -v grep | wc -l)
        if [ "$mongo_count" -eq 0 ]; then
            echoColor red "错误：MongoDB 8 未能正常启动"
            echoColor yellow "正在查看日志文件：$dbpath/ehr/mongodb8/logs/mongodb.log"
            echoColor red "========== 日志内容开始 =========="
            if [ -f "$dbpath/ehr/mongodb8/logs/mongodb.log" ]; then
                cat "$dbpath/ehr/mongodb8/logs/mongodb.log"
            else
                echoColor red "日志文件不存在：$dbpath/ehr/mongodb8/logs/mongodb.log"
            fi
            echoColor red "========== 日志内容结束 =========="
            log_message "ERROR: MongoDB 8 failed to start. Check mongodb.log for details"
            exit $EXIT_FAILURE
        fi
        
        # 初始化数据库
        if [ -f $dbpath/ehr/mongodb8/mongosh/bin/mongosh ]; then
            $dbpath/ehr/mongodb8/mongosh/bin/mongosh 127.0.0.1:27011/ehr -u ehr -p kh5MCLQRhe "$dbpath/ehr/inti_MongoDB_index.js" >> "$logpath/install.log" 2>&1
            $dbpath/ehr/mongodb8/mongosh/bin/mongosh 127.0.0.1:27011/ehr -u ehr -p kh5MCLQRhe "$dbpath/ehr/init_MongoDB_App.js" >> "$logpath/install.log" 2>&1
        else
            echoColor yellow "警告：mongosh 命令不存在，跳过数据库初始化"
            log_message "WARNING: mongosh command not found, skipped database initialization"
        fi
        
        echoColor green "已成功安装并启动 MongoDB 8 (ARM 版本)，安装路径为 $dbpath/ehr/mongodb8"
        log_message "MongoDB 8 ARM version installed and started successfully"
    else
        echoColor red "错误：未找到适用于 ARM 架构的 MongoDB 安装包"
        echoColor yellow "提示：请确保安装包文件名包含 'mongodb' 和 'aarch' 关键字"
        log_message "ERROR: No ARM-compatible MongoDB 8 package found"
        exit $EXIT_FAILURE
    fi
}

#判断服务器操作系统版本选择安装相应版本 mongodb 服务，相应系统下增加判断 cpu 是否支持 avx 指令集
installMongoDB8() {
    # 获取 CPU 架构
    CPU_ARCH=$(uname -m)
    
    case "$CPU_ARCH" in
        x86_64|i386|i686)
            # x86 架构需要检查 AVX 指令集
            if ! grep -q avx /proc/cpuinfo; then
                echoColor red "错误：x86/x64 架构 CPU 不支持 AVX 指令集，无法安装 MongoDB 8"
                echoColor red "请确认服务器硬件配置或联系系统管理员"
                log_message "ERROR: x86/x64 CPU does not support AVX instructions"
                exit $EXIT_FAILURE
            fi
            installMongoDB8_x86
            ;;
        aarch64|armv7l|armv6l)
            installMongoDB8_ARM
            ;;
        *)
            echoColor red "错误：未识别的 CPU 架构：$CPU_ARCH"
            echoColor red "本系统仅支持 x86/x64 和 ARM 架构服务器"
            log_message "ERROR: Unsupported CPU architecture: $CPU_ARCH"
            exit $EXIT_FAILURE
            ;;
    esac
}


#服务是否安装判断
isInstall() {
	Tomcat="tomcat"

	PGSQL="postgres"

	MongoDB="mongod"

	if [ $# -ne 1 ];then
		echo "Usage $0 content {tomcat|postgres|mongod}"
		exit
	fi
	case "$1" in	
		mongod|MONGOD)
			if [ -f "$dbpath/ehr/mongodb8/bin/mongod" ] || [ -f "$dbpath/ehr/mongodb6/bin/mongod" ] || [ -f "$dbpath/ehr/mongodb/bin/mongod" ]
			then
				echoColor red "mongodb 已安装"
			else
				echoColor green "mongodb 未安装"
				return 1
			fi
			;;
		postgres|POSTGRES)	
			if	[ -f "$dbpath/ehr/postgresql15/bin/psql" ]
			then
				echoColor red "postgresql已安装"
			else
				echoColor green "postgresql未安装"
				return 1
			fi
			;;
		tomcat|TOMCAT)
			if	[ -f "$webpath/dhr/dhr.war" ]
			then
				echoColor red "tomcat已安装"
			else
				echoColor green "tomcat未安装"
				return 1
			fi
			;;
		*)
        	echo "请输入指定的服务名称：{tomcat|postgres|mongod}"
			;;
	esac
}

############################################################################

# 初始化数据库路径和配置
initDbPath() {
    # 如果不存在path文件,则交互式输入
    if [ ! -f /tmp/dbpath.txt ]; then
        dbPathInput
    else
        echoColor yellow "检测到已存在的path文件,跳过变量赋值"
    fi
    
    # 读取并验证路径
    if [ ! -f /tmp/dbpath.txt ]; then
        echoColor red "错误: 无法获取数据库安装路径"
        exit $EXIT_FAILURE
    fi
    
    # 去除末尾的 / (如果存在)
    local content=$(cat /tmp/dbpath.txt)
    content=${content%/}
    echo "$content" > /tmp/dbpath.txt
    
    # 导出全局变量
    export dbpath="$content"
    
    # 创建目录
    mkdir -p "$dbpath/ehr" || {
        echoColor red "错误: 无法创建目录 $dbpath/ehr"
        exit $EXIT_FAILURE
    }
    
    echoColor green "数据库安装路径: $dbpath/ehr"
    log_message "Database installation path: $dbpath/ehr"
}

############################################################################

# 初始化数据库路径
initDbPath

# 更新MongoDB脚本中的路径变量
#sedMongodb8path

# 检查 CPU 架构和 AVX 指令集支持
#checkCPUArchAndAVX

# 修改文件描述符限制
if ! grep -q "root soft nofile 65535" /etc/security/limits.conf 2>/dev/null; then
    echo "root soft nofile 65535" >> /etc/security/limits.conf
    echo "root hard nofile 65535" >> /etc/security/limits.conf
    echoColor green "已更新文件描述符限制"
fi

# 检查并安装MongoDB
if isInstall mongod; then
    echoColor red "MongoDB 已存在,跳过安装"
    log_message "MongoDB already exists, skipped installation"
    exit $EXIT_SUCCESS
else
    installMongoDB8
fi
