#!/usr/bin/env bash

export RSYNC_REMOTE="screen@rsync.inner.xcastle.net::screen"
export CONFIG_FILE="/data/global.yaml"
export MIRROR_HOST="mirrors.huaweicloud.com"

declare -A COMMAND_PKG_MAP=(
  ["curl"]="curl"
  ["jq"]="jq"
  ["wget"]="wget"
  ["nc"]="netcat"
)

install_command_if_needed() {
  local cmd=$1
  command -v "$cmd" &>/dev/null && { return 0; }

  local pkg="${COMMAND_PKG_MAP[$cmd]}"
  [[ -z "$pkg" ]] && { echo "未找到 '$cmd' 对应的安装包"; exit 1; }

  if ! apt-cache policy "$pkg" | grep -q -E 'Candidate:|候选' ; then
    apt update -qq  >/dev/null 2>&1
  fi
  echo "安装 '$cmd' (包: $pkg)"
  apt install -y -qq "$pkg" >/dev/null 2>&1
}

install_pkg_if_needed() {
  local pkg=$1
  if ! apt-cache policy "$pkg" | grep -q -E 'Candidate:|候选' ; then
    apt update -qq >/dev/null 2>&1
  fi
  if ! dpkg -l | grep -q "$pkg"; then
    echo "安装包: $pkg"
    apt install -y -qq "$pkg" >/dev/null 2>&1
  fi
}


getScreenNum() {
  local old_config_file="/data/global.conf"

  if [[ -f "$CONFIG_FILE" ]]; then
    screenNum=$(grep -oP '^\s*screenNum\s*:\s*"\K[\w\-]+' "$CONFIG_FILE")
  else
    ## from old
    if [[ -f "$old_config_file" ]]; then
      screenNum=$(grep -oP '^\s*screenNum\s*=\s*\K[\w\-]+' "$old_config_file")
    fi
    cat > $CONFIG_FILE <<EOF
screenNum: "$screenNum"
env: "prod"
EOF
    rm -f $old_config_file
  fi

  if [[ -z "$screenNum" ]]; then
    read -p "请输入设备号: " screenNum
    cat > $CONFIG_FILE <<EOF
screenNum: "$screenNum"
env: "prod"
EOF
  fi
  echo "$screenNum"
}

getEnv() {
  if [ ! -f "$CONFIG_FILE" ]; then
    echo "dev"
    return 0
  fi
  echo $(grep '^env:' $CONFIG_FILE| awk '{print $2}' | tr -d '"' || echo "prod")
}

status_icon() {
  [ $? -eq 0 ] && echo -e "\e[32m✓✓\e[0m" || echo -e "\e[31m✗✗\e[0m"
}

rrsync() {
  local sc=''
  if [ "$DEBUG" = true ]; then
    sc=' -v -P'
  fi
  rsync $sc --timeout=10 "$@"
}

getLoginUid() {
  local uid=$(loginctl list-sessions --no-legend | grep -E "tty|seat" | awk '{print $2}' | head -n 1)
  if [[ "$uid" == '' ]]; then
     uid=$(loginctl list-sessions --no-legend | awk '{print $2}' | head -n 1)
  fi
  echo $uid
}

## <- agent begin
UPGRADE_LOG_FILE='/data/agent/upgrade.log'

logUpgrade() {
  echo $(date '+%Y-%m-%d %H:%M:%S') "$@" >> $UPGRADE_LOG_FILE
}

rsyncFlutterNew() {
  echo "同步flutterNew"

  local uid=$(getLoginUid)
  local username=$(id -nu $uid)

  rrsync -a --chown=${username}:${username} "${RSYNC_REMOTE}/apps/flutter/${appBranch}/${flutterVersion}/" /data/flutter_new/
  
  if [[ "$appBranch" == 'human-zhong' ]]; then
    tt_nums=("062" "071" "073" "074" "118" "119" "120")
    if [[ ! " ${tt_nums[*]} " =~ " $screenNum " ]]; then
      echo '覆盖通用声音'
      rrsync -a --chown=${username}:${username} "${RSYNC_REMOTE}/apps/flutter/indexWidget2.wav" /data/flutter_new/data/flutter_assets/assets/audios/
    fi
  fi
  status_icon
}

syncDockerServicesNew() {
  mkdir -p /tmp/lib.sh
  logUpgrade "同步打印和算法"

  # 生成临时配置 0自动 1为手动win, 2手动linux
  if [ "$printType" == 1 ]; then
    logUpgrade 生成手动配置
    renderTpl ./compose-tpl-human.yaml /tmp/tmp-docker-compose.yaml
  else
    logUpgrade 生成自动配置
    renderTpl ./compose-tpl.yaml  /tmp/tmp-docker-compose.yaml
  fi

  mv /tmp/tmp-docker-compose.yaml /data/services_new/docker-compose.yaml
  docker compose -f /data/services_new/docker-compose.yaml pull
  
  status_icon
}

updateLocalDockerAndFlutterService(){
  local uid=$(getLoginUid)
  local username=$(id -nu $uid)

  if [ "$needDocker" == 1 ]; then
    mv /data/services_new/* /data/services/ && \
    cd /data/services && \
    docker compose pull && \
    docker compose up -d
  fi

  if [ "$needFlutter" == 1 ]; then
    su "$username" -s /bin/bash <<EOF
    export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$uid/bus"
    rsync -a /data/flutter_new/* /data/flutter/ && \
    rm -rf /data/flutter_new/* && \
    systemctl --user restart kadaya.service
EOF
  fi
}
## agent end ->

function renderTpl(){
  [ $# = 0 ] && echo "模板参数不能为空" && exit 1
  [ ! -f $1 ] && echo "$1 模板文件不存在" && exit 1
  str="$(cat $1)"
  while [[ "$str" =~ (\{\{[ ]*(\$[a-zA-Z_][a-zA-Z_0-9]*)[ ]*\}\}) ]]; do
    tpl=${BASH_REMATCH[1]}
    name=${BASH_REMATCH[2]}
    val="$(eval echo $name)"
    if [ "$val" = "" ]; then
     echo "$name 变量不存在或值为空 line:$line"
     exit 1
    fi
    str=${str//$tpl/$val}
  done; echo "$str" > $2
}

detectSystem() {
  DISTRO_NAME=$(bash -c "if grep -q 'Ubuntu' /etc/os-release; then echo 'ubuntu'; \
    elif grep -q 'Debian' /etc/os-release; then echo 'debian'; fi")

  echo "$DISTRO_NAME"
}

function detectSystem2() {
  local -n resultMap=$1
  
  tmp=$(bash <<'EOF'
echo system=$(if grep -q 'Ubuntu' /etc/os-release; then echo 'ubuntu'; elif grep -q 'Debian' /etc/os-release; then echo 'debian'; fi)
echo "hostname=$(hostname)"
EOF
  )

  while IFS='=' read -r key value; do
      resultMap["$key"]=$value
  done <<< "$tmp"
}

checkAndchangeMirrors() {
  local codename=$(grep 'VERSION_CODENAME' /etc/os-release | cut -d'=' -f2)
  local id=$(grep '^ID=' /etc/os-release| cut -d'=' -f2)

  # apt source
  local apt_content=$(cat /etc/apt/sources.list 2>/dev/null)
  local new_apt_content
  if [ "$id" == 'debian' ]; then
    new_apt_content=$(cat <<EOF
deb http://${MIRROR_HOST}/debian/ ${codename} main contrib non-free non-free-firmware
deb http://${MIRROR_HOST}/debian/ ${codename}-updates main contrib non-free non-free-firmware
deb http://${MIRROR_HOST}/debian/ ${codename}-backports main contrib non-free non-free-firmware
deb http://${MIRROR_HOST}/debian-security ${codename}-security main contrib non-free non-free-firmware
EOF
)
  else
    new_apt_content=$(cat <<EOF
deb http://${MIRROR_HOST}/ubuntu/ ${codename} main restricted universe multiverse
deb http://${MIRROR_HOST}/ubuntu/ ${codename}-updates main restricted universe multiverse
deb http://${MIRROR_HOST}/ubuntu/ ${codename}-backports main restricted universe multiverse
deb http://${MIRROR_HOST}/ubuntu/ ${codename}-security main restricted universe multiverse
EOF
)
  fi

  new_docker_content="deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] http://${MIRROR_HOST}/docker-ce/linux/${id} ${codename} stable"
  if [ -f '/etc/apt/sources.list.d/docker.list' ]; then
     echo "$new_docker_content" > /etc/apt/sources.list.d/docker.list
  fi

  if [ "$apt_content" != "$new_apt_content" ]; then
    echo "更新 /etc/apt/sources.list"
    echo "$new_apt_content" > /etc/apt/sources.list
    apt update || true
  fi
}

fixLogin() {
  echo "修复登录账号"
  local screenNum=$1

  if [ ! -f /root/.ssh/authorized_keys ]; then
    mkdir -p /root/.ssh
    echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDUyM4MaPZzM7+ElPfQbDStxXtzN2X5/dxGtwT0N6T8DhzlrN8bfl9JRpCCSNT8YtkUCN9R75cHDJSk7DHH7QsgWlTjwXvQpERFoLQ2E5syn9g0jBk+RsmNgLqcNqL7fz8Zzp9Yt1OX9Fwzn9DPmKHjJjnazngvE2vmSBuau75aCa84cqSj9jkduVR4yBCP4UJLNTIzVU8VRZwrrPUKUd9UXrAFxVVpTD0bJQMS3PoPmoZehdZB6GExf8+unCUwBmcHqK4Xq9lTBFZCtSDEaZcxm6sjQbwIH73zzIC3bn6qrl+94tHmAvYM+gkhJqbUizGO4UN9rCxb3Zcey78E5Yy8hGvZ33eH9bL0O5wmvMuAkNDuWrcGa+0wpTMawANr3XM4jscMaAhznpSJQwvsZJSJ7vOu73b2+IHwP2t65K+cmn9zm+J7yoiMhEyLaSI7zR/UACSE8Qra9WN3ogxzZeQWkdU8SUfh+2EgDveUPdZ9XwSG0exWYEU/fLhTYJJlznM= root@ms000' >/root/.ssh/authorized_keys
    chmod 600 /root/.ssh/authorized_keys

    sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config
    systemctl restart sshd
    systemctl restart ssh
  fi

  if [ -d /home/txry ] && [ ! -f /home/txry/.ssh/authorized_keys ]; then
    mkdir -p /home/txry/.ssh
    echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDUyM4MaPZzM7+ElPfQbDStxXtzN2X5/dxGtwT0N6T8DhzlrN8bfl9JRpCCSNT8YtkUCN9R75cHDJSk7DHH7QsgWlTjwXvQpERFoLQ2E5syn9g0jBk+RsmNgLqcNqL7fz8Zzp9Yt1OX9Fwzn9DPmKHjJjnazngvE2vmSBuau75aCa84cqSj9jkduVR4yBCP4UJLNTIzVU8VRZwrrPUKUd9UXrAFxVVpTD0bJQMS3PoPmoZehdZB6GExf8+unCUwBmcHqK4Xq9lTBFZCtSDEaZcxm6sjQbwIH73zzIC3bn6qrl+94tHmAvYM+gkhJqbUizGO4UN9rCxb3Zcey78E5Yy8hGvZ33eH9bL0O5wmvMuAkNDuWrcGa+0wpTMawANr3XM4jscMaAhznpSJQwvsZJSJ7vOu73b2+IHwP2t65K+cmn9zm+J7yoiMhEyLaSI7zR/UACSE8Qra9WN3ogxzZeQWkdU8SUfh+2EgDveUPdZ9XwSG0exWYEU/fLhTYJJlznM= root@ms000' >/home/txry/.ssh/authorized_keys
    chmod 600 /home/txry/.ssh/authorized_keys
    chown txry:txry /home/txry/.ssh/authorized_keys
  fi

  status_icon
}

prepareSystem() {
  echo 环境一致性修正
  local pversion='1.0.4'
  local pversion_file='/data/.screen_prepare'
  if [ -f "$pversion_file" ] && [ "$(cat "$pversion_file")" = "$pversion" ]; then
    echo "已经prepare了，当前版本：$pversion"
    status_icon
    return 0
  fi

  echo
  cleanOld

  echo
  cmd_installFrp --check

  echo
  cmd_installRustdesk --check

  if [ $systemId == "ubuntu" ]; then
    echo
    prepareUbuntu
  else
    echo
    prepareDebian
  fi

  echo "$pversion" > $pversion_file
  status_icon
}

prepareUbuntu() {
  # 禁用密码登录
  echo '禁用密码登录'
  sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config

  echo 'NetworkManager健康和切换配置'
  rsync /data/screen/20-health-and-metric.conf /etc/NetworkManager/conf.d/ >/dev/null 2>&1

  # 新的打印服务依赖root密码
  echo 重制root密码
  echo 'root:txry'|chpasswd 2>&1 || true

  echo 修改更新源
  checkAndchangeMirrors

  echo 禁用ubuntu自动升级
  systemctl stop unattended-upgrades.service >/dev/null 2>&1 || true
  systemctl disable unattended-upgrades.service >/dev/null 2>&1 || true
  apt remove -y unattended-upgrades >/dev/null 2>&1 || true

  echo 禁用cups不需要的服务
  systemctl disable avahi-daemon.service avahi-daemon.socket cups-browsed.service >/dev/null 2>&1 || true
  systemctl mask avahi-daemon.service avahi-daemon.socket cups-browsed.service >/dev/null 2>&1 || true

  # 只保留usb
  echo 禁用打印不需要的后端
  chmod a-x /usr/lib/cups/backend/{dnssd,ipp,ipps,lpd,parallel,serial,snmp,socket} >/dev/null 2>&1 || true

  echo 检查cy打印驱动
  install_pkg_if_needed printer-driver-gutenprint

  echo 检查epson打印驱动
  install_pkg_if_needed printer-driver-escpr

  echo 安装epson8168驱动
  apt install -y /data/screen/epson-inkjet-printer-escpr2_1.2.33-1_amd64.deb >/dev/null 2>&1 || true

  echo 卸载向日葵
  apt remove -y sunloginclient >/dev/null 2>&1 || true

}

prepareDebian() {
  echo 'NetworkManager健康和切换配置'
  rsync /data/screen/20-health-and-metric.conf /etc/NetworkManager/conf.d/ >/dev/null 2>&1

  # 新的打印服务依赖root密码
  echo 重制root密码
  echo 'root:txry'|chpasswd 2>&1 || true

  echo 禁用cups不需要的服务
  systemctl disable avahi-daemon.service avahi-daemon.socket cups-browsed.service >/dev/null 2>&1 || true
  systemctl mask avahi-daemon.service avahi-daemon.socket cups-browsed.service >/dev/null 2>&1 || true

  # 只保留usb
  echo 禁用打印不需要的后端
  chmod a-x /usr/lib/cups/backend/{dnssd,ipp,ipps,lpd,parallel,serial,snmp,socket} >/dev/null 2>&1 || true

  echo 检查cy打印驱动
  install_pkg_if_needed printer-driver-gutenprint

  echo 安装epson816x驱动
  apt install -y /data/screen/epson-inkjet-printer-escpr2_1.2.33-1_amd64.deb >/dev/null 2>&1 || true

}

rsyncFlutter() {
  echo "同步flutter"

  local uid=$(getLoginUid)
  local username=$(id -nu $uid)

  if [[ "$flutterSpecifiedVersion" != "null" && -n "$flutterSpecifiedVersion" ]]; then
    flutterVersion="$flutterSpecifiedVersion"
  fi
  echo "Flutter 指定版本: $flutterVersion"

  rrsync -a --chown=${username}:${username} "${RSYNC_REMOTE}/apps/flutter/${appBranch}/${flutterVersion}/" /data/flutter/
  
  if [[ "$appBranch" == 'human-zhong' ]]; then
    tt_nums=("062" "071" "073" "074" "118" "119" "120")
    if [[ ! " ${tt_nums[*]} " =~ " $screenNum " ]]; then
      echo '覆盖通用声音'
      rrsync -a --chown=${username}:${username} "${RSYNC_REMOTE}/apps/flutter/indexWidget2.wav" /data/flutter/data/flutter_assets/assets/audios/
    fi
  fi

  # 修正目录权限
  mkdir -p /data/files
  mkdir -p /data/services
  chown ${username}:${username} -R /data/files
  chown ${username}:${username} -R /data/flutter

  # 桌面图标
  if [ "$username" == "root" ]; then
    local desktopDir="/root/Desktop/"
    [ -d "/root/桌面/" ] && desktopDir="/root/桌面/"
    cp -f /data/screen/卡达鸭.desktop $desktopDir
    chmod +x ${desktopDir}卡达鸭.desktop
  else
    local desktopDir="/home/${username}/Desktop/"
    [ -d "/home/${username}/桌面/" ] && desktopDir="/home/${username}/桌面/"

    cp -f /data/screen/卡达鸭.desktop $desktopDir
    chown ${username}:${username} ${desktopDir}卡达鸭.desktop
    chmod +x ${desktopDir}卡达鸭.desktop
    su "$username" -s /bin/bash <<EOF
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus"
gio set ${desktopDir}卡达鸭.desktop metadata::trusted true
EOF
  fi

  status_icon
}

setupFlutterService() {
  echo '设置flutter启动服务'

  local uid=$(getLoginUid)
  local username=$(id -nu $uid)

  if [ "$username" == "root" ]; then
    mkdir -p /root/.config/systemd/user/
    cp -f /data/screen/kadaya.service /root/.config/systemd/user/kadaya.service
    systemctl --user daemon-reload
    systemctl --user enable kadaya.service
  else
    su "$username" -s /bin/bash <<EOF
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$uid/bus"
mkdir -p /home/${username}/.config/systemd/user/
cp -f /data/screen/kadaya.service /home/${username}/.config/systemd/user/kadaya.service
systemctl --user daemon-reload
systemctl --user enable kadaya.service
EOF

  fi

  status_icon
}


cleanOld() {
  echo '清理旧配置'

  local uid=$(getLoginUid)
  local username=$(id -nu $uid)
  
  # clean old magicscreen-docker.service
  systemctl disable magicscreen-docker.service >/dev/null 2>&1 || true
  rm -f /etc/systemd/system/magicscreen-docker.service || true

  # clean old magicscreen_start.service
  systemctl disable magicscreen_start.service >/dev/null 2>&1 || true
  rm -f /etc/systemd/system/magicscreen_start.service || true

  # clean old magicscreen.service
  systemctl disable magicscreen.service >/dev/null 2>&1 || true
  rm -f /etc/systemd/system/magicscreen.service || true

  # clean old magicscreen.service
  if [ "$username" == "root" ]; then
    systemctl --user diable magicscreen.service >/dev/null 2>&1 || true
    rm -f /root/.config/systemd/user/magicscreen.service || true
  else
    su "$username" -s /bin/bash <<EOF
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$uid/bus"
systemctl --user diable magicscreen.service >/dev/null 2>&1 || true
rm -f /home/$username/.config/systemd/user/magicscreen.service || true
rm -f /home/$username/Desktop/MagicScreenSdk.desktop || true
EOF

  fi

  status_icon
}

syncDockerServices() {
  echo "同步打印和算法"

  # 同步老的权重文件 如果存在
  SOURCE_WEIGHTS_DIR="/home/txry/MagicScreen/weights/"
  TARGET_WEIGHTS_DIR="/data/algorithmService/weights/"

  if [ -d "$SOURCE_WEIGHTS_DIR" ]; then
    mkdir -p "$(dirname "$TARGET_WEIGHTS_DIR")"
    rsync -a --chown=txry:txry "$SOURCE_WEIGHTS_DIR" "$TARGET_WEIGHTS_DIR"
    rm -rf $SOURCE_WEIGHTS_DIR
  fi

  if [[ "$algorithmSpecifiedVersion" != "null" && -n "$algorithmSpecifiedVersion" ]]; then
    algorithmServiceVersion="$algorithmSpecifiedVersion"
  fi
  if [[ "$printSpecifiedVersion" != "null" && -n "$printSpecifiedVersion" ]]; then
    printServiceVersion="$printSpecifiedVersion"
  fi
  echo "Algorithm 指定版本: $algorithmServiceVersion"
  echo "Print 指定版本: $printServiceVersion"

  # 生成临时配置 0自动 1为手动win, 2手动linux
  if [ "$printType" == 1 ]; then
    echo 生成手动配置
    renderTpl ./compose-tpl-human.yaml /tmp/tmp-docker-compose.yaml
  else
    echo 生成自动配置
    renderTpl ./compose-tpl.yaml  /tmp/tmp-docker-compose.yaml
  fi
  mv /tmp/tmp-docker-compose.yaml /data/services/docker-compose.yaml


  mkdir -p /data/files
  mkdir -p /data/services

  # 同步服务文件
  cp -f /data/screen/kadaya-boot.service /etc/systemd/system/kadaya-boot.service
  systemctl daemon-reload
  systemctl enable kadaya-boot.service

  # 如果docker服务未运行 默认启动
  cd /data/services
  docker compose pull
  if docker compose ps | grep -q "algorithmService"; then
    echo "Docker Compose服务已在运行中."
  else
    echo "Docker Compose服务未运行，正在启动..."
    docker compose up -d
  fi

  status_icon
}

reportVersion() {
  echo "上报当前版本"

  install_command_if_needed curl

  env=$(getEnv)
  api='https://api-magicscreen.xcastle.net/mp/screenVersion/reportingVersion'
  if [ "$env" == 'dev' ]; then
    api='https://test-api-magicscreen.xcastle.net/mp/screenVersion/reportingVersion'
  fi

  curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "screenNumber": "'"$screenNum"'",
    "downloadedVersion": {
      "flutter": "'"$flutterVersion"'",
      "algorithm": "'"$algorithmServiceVersion"'",
      "print": "'"$printServiceVersion"'"
    }
  }' \
  --max-time 5 \
  --silent \
  --fail \
  $api

  status_icon
}

syncScreen() {
  echo "同步screen目录"

  rrsync -a --delete --exclude='version.sh' "${RSYNC_REMOTE}/apps/screen/" /data/screen/

  status_icon
}

syncGlobalConfig() {
  echo "同步全局配置"
  
  renderTpl ./global-tpl.yaml /tmp/tmp-global.yaml

  # 同步配置文件
  mv /tmp/tmp-global.yaml /data/global.yaml

  status_icon
}

repairDocker() {
  echo "检查并安装docker"

  bash /data/screen/repair_docker.sh
  status_icon
}

getAppBranch() {
  install_command_if_needed jq
  
  local url="https://api-magicscreen.xcastle.net/mp/screen/config?screenNumber=${screenNum}"
  response=$(curl -s "$url")
  if [ $? -ne 0 ]; then
      echo "Error: 请求大屏配置失败 $response" 
      exit 1
  fi
  
  code=$(echo "$response" | jq -r '.code')
  msg=$(echo "$response" | jq -r '.msg')
  printType=$(echo "$response" | jq -r '.data.printType')
  appBranch=$(echo "$response" | jq -r '.data.appBranch')

  if [ "$code" != "100" ]; then
      echo "Error: 请求大屏配置失败 $msg"
      exit 1
  fi

  if [ "$printType" == "null" ] || [ -z "$printType" ]; then
      printType="0"
  fi
  if [ "$appBranch" == "null" ] || [ -z "$appBranch" ]; then
      appBranch="human-zhong"
  fi

  export printType="$printType"
  export appBranch="$appBranch"
  flutterSpecifiedVersion=$(echo "$response" | jq -r '.data.screenVersion.specifiedVersion.flutter // ""')
  algorithmSpecifiedVersion=$(echo "$response" | jq -r '.data.screenVersion.specifiedVersion.algorithm // ""')
  printSpecifiedVersion=$(echo "$response" | jq -r '.data.screenVersion.specifiedVersion.print // ""')
  export flutterSpecifiedVersion="$flutterSpecifiedVersion"
  export algorithmSpecifiedVersion="$algorithmSpecifiedVersion"
  export printSpecifiedVersion="$printSpecifiedVersion"
  echo "Flutter 指定版本: $flutterSpecifiedVersion"
  echo "Algorithm 指定版本: $algorithmSpecifiedVersion"
  echo "Print 指定版本: $printSpecifiedVersion"
}

cmd_installFrp() {
  echo "安装 frp"

  install_command_if_needed curl

  local serviceName='frpc'

  if [[ "$*" == *"--check"* ]]; then
    if ! systemctl list-units --type=service --all | grep -q "$serviceName"; then
      bash -c "$(curl https://file.inner.xcastle.net/boot.sh)"  --  -install ${serviceName}
    else
      echo "${serviceName}已安装了"
    fi
  else
    bash -c "$(curl https://file.inner.xcastle.net/boot.sh)"  --  -install ${serviceName}
  fi

  status_icon
}

cmd_installRustdesk() {
  echo "安装 rustdesk"

  install_command_if_needed curl

  local serviceName='rustdesk'

  if [[ "$*" == *"--check"* ]]; then
    if ! systemctl list-units --type=service --all | grep -q "$serviceName"; then
      bash -c "$(curl https://file.inner.xcastle.net/boot.sh)"  --  -install ${serviceName}
    else
      echo "${serviceName}已安装了"
    fi
  else
    bash -c "$(curl https://file.inner.xcastle.net/boot.sh)"  --  -install ${serviceName}
  fi

  status_icon
}

cmd_setVolume() {
  local value="${1:-60}"

  local uid=$(getLoginUid)
  local username=$(id -nu $uid)

  if [ "$username" == "root" ]; then
    amixer -D pulse sset Master ${value}%
  else

    # 设置hdmi声音输出
    su "$username" -s /bin/bash <<EOF
export XDG_RUNTIME_DIR="/run/user/${uid}"
targetOut='output:hdmi-stereo'
set -exu
pactl get-default-sink
# repair hdmi output?
if ! pactl get-default-sink | grep 'hdmi' && pactl list short sinks | grep 'hdmi'; then
  echo 设置声卡输出为hdmi
  cardName=\$(pactl list cards | grep -E '^\s*Name: alsa_card\.pci-' | awk '{print \$2}' | head -n 1)
  pactl set-card-profile \$cardName \$targetOut
  sinkIndex=\$(pactl list short sinks|grep hdmi|awk '{print \$1}'|head -n 1)
  pactl set-default-sink \$sinkIndex
fi

amixer -D pulse sset Master ${value}% 
EOF

# 设为模拟输出
#   su "$username" -s /bin/bash <<EOF
# export XDG_RUNTIME_DIR="/run/user/${uid}"
# targetOut='output:analog-stereo'
# set -exu
# pactl get-default-sink
# if ! pactl get-default-sink | grep 'analog'; then
#   echo 设置声卡输出为analog
#   cardName=\$(pactl list cards | grep -E '^\s*Name: alsa_card\.pci-' | awk '{print \$2}' | head -n 1)
#   pactl set-card-profile \$cardName \$targetOut
#   sinkIndex=\$(pactl list short sinks|grep analog|awk '{print \$1}'|head -n 1)
#   pactl set-default-sink \$sinkIndex
# fi

# amixer -D pulse sset Master 100% 
# EOF

  fi

  status_icon
}

cmd_showVolume() {
  local uid=$(getLoginUid)
  local username=$(id -nu $uid)

  if [ "$username" == "root" ]; then
    amixer -D pulse sget Master
  else
    su "$username" -s /bin/bash <<EOF
export XDG_RUNTIME_DIR="/run/user/${uid}"
targetOut='output:hdmi-stereo'
set -exu
amixer -D pulse sget Master  
EOF
  fi

  status_icon
}


#校正摄像头
cmd_updateDirection() {
  local input_value="${1:-0}"  # 默认传入参数为 0（如果未提供）
  local direction_config_file="/data/flutter/config.json"
  local current_direction
  # 检查文件是否存在
  if [ ! -f "$direction_config_file" ]; then
    echo "INFO: create config file at $direction_config_file"
    echo '{"direction": 1}' > "$direction_config_file"
    current_direction=1
  else
	# 使用 jq 读取当前 direction 值
    current_direction=$(jq -r '.direction' "$direction_config_file")
  fi
 
  # 检查是否成功读取
  if [ "$current_direction" == "null" ] || [ -z "$current_direction" ]; then
    echo "Error: Failed to parse 'direction' from $direction_config_file"
    return 1
  fi
 
  # 计算新值：（当前值 + 输入值）模 4（确保结果在 1~4 之间循环）
  local new_direction=$(( (current_direction + input_value - 1) % 4 + 1 ))
 
  # 使用 jq 更新 JSON 文件（保持格式不变）
  if ! (jq -c --argjson new_dir "$new_direction" '.direction = $new_dir' "$direction_config_file" > tmp.json && mv tmp.json "$direction_config_file"); then
    echo "Error: Failed to update $direction_config_file"
    return 1
  fi
 
  echo "Successfully updated direction: $current_direction -> $new_direction"
  
  status_icon
}

#启用或禁用更新agent
cmd_enableOrDisableAgent() {
  local input_op_value="${1:-0}"  # 默认传入参数为 0（如果未提供）
  local agent_source_file="/data/screen/agent"
  local agent_file="/data/agent/agent"
  if [ ! -f "$agent_file" ]; then
    mkdir -p /data/agent
  fi
  if [ "$input_op_value" -eq 1 ]; then
    echo "启用更新agent"
    systemctl stop kadaya-agent.service
    cp $agent_source_file $agent_file
    cp -f /data/screen/kadaya-agent.service /etc/systemd/system/kadaya-agent.service
    systemctl daemon-reload
    systemctl enable kadaya-agent.service
    systemctl start kadaya-agent.service
    echo "启用更新agent成功"
  elif [ "$input_op_value" -eq 0 ]; then
    echo "禁用更新agent"
    systemctl disable kadaya-agent.service
    systemctl stop kadaya-agent.service
  else
    echo "无效的输入参数"
  fi
  status_icon
}

cmd_fixLogin() {
  fixLogin $screenNum
}

cmd_upgradeFlutter() {
  getAppBranch

  echo "程序版本 分支:${appBranch}, 打印方式(0自动 1手动):${printType}"
  cat "./version_${appBranch}.sh"
  source "./version_${appBranch}.sh"
  echo
  echo '----'

  echo
  rsyncFlutter

  echo
  reportVersion
  # 使用 sed 替换文件中的变量值
  sed -i \
      -e "s|^flutterVersion=.*|flutterVersion=\"$flutterVersion\"|" \
      "/data/screen/version.sh"
}

cmd_upgradeServices() {
  getAppBranch

  echo "程序版本 分支:${appBranch}, 打印方式(0自动 1手动):${printType}"
  cat "./version_${appBranch}.sh"
  source "./version_${appBranch}.sh"
  echo
  echo '----'

  echo
  repairDocker

  echo 
  syncDockerServices
  # 使用 sed 替换文件中的变量值
  sed -i \
      -e "s|^printServiceVersion=.*|printServiceVersion=\"$printServiceVersion\"|" \
      -e "s|^algorithmServiceVersion=.*|algorithmServiceVersion=\"$algorithmServiceVersion\"|" \
      "/data/screen/version.sh"
}

cmd_deploy() {
  getAppBranch

  echo "程序版本 分支:${appBranch}, 打印方式(0自动 1手动):${printType}"
  cat "./version_${appBranch}.sh"
  source "./version_${appBranch}.sh"
  echo
  echo '----'

  echo
  syncGlobalConfig

  echo
  repairDocker

  echo
  rsyncFlutter

  echo
  setupFlutterService

  echo 
  syncDockerServices

  echo '保存版本'
  cp -f "/data/screen/version_${appBranch}.sh" "/data/screen/version.sh" 

  # 使用 sed 替换文件中的变量值
  sed -i \
      -e "s|^flutterVersion=.*|flutterVersion=\"$flutterVersion\"|" \
      -e "s|^printServiceVersion=.*|printServiceVersion=\"$printServiceVersion\"|" \
      -e "s|^algorithmServiceVersion=.*|algorithmServiceVersion=\"$algorithmServiceVersion\"|" \
      "/data/screen/version.sh"

  echo
  echo '-----程序更新已完成-----'

  echo 清理docker
  docker system prune -a --force --filter "until=720h"
  status_icon

  echo
  prepareSystem

  echo
  reportVersion

  echo
  echo "部署完成！撒花🎉"
}

cmd_prepareSystem() {
  echo
  prepareSystem
}

function show_help() {
    echo "用法: $0 {cmd} [args] [--screenNum 001] [--sync] [--debug] [--help]"
    echo "  {cmd} deploy|upgradeFlutter|upgradeServices|prepareSystem|fixLogin|setVolume|installFrp|installRustdesk 部署|升级flutter|升级服务|环境修正|修复登录|设置音量|安装frp|安装rustdesk"
    echo "  [args]       cmd的参数" 
    echo "  --screenNum  设备码(默认从配置读取)"
    echo "  --sync       执行前先更新"
    echo "  --debug      启用调试信息"
    echo "  --help       显示帮助"
    exit 1
}


function parsArgs() {
  DEBUG=false
  IS_SYNC=false
  CMD=""
  CMD_ARGS=()
  screenNum=""
  args=("${@}")

  if [ $# -eq 0 ]; then
    show_help
  fi

  while [[ $# -gt 0 ]]; do
      case "$1" in
          --debug)
              DEBUG=true
              shift
              ;;
          --sync)
              IS_SYNC=true
              shift
              ;;
          --screenNum)
              if [[ -n $2 ]]; then
                  screenNum=$2
                  shift 2
              else
                  echo "Error: --screenNum 设备码不能为空"
                  show_help
              fi
              ;;
          *)
              if [[ -z "$CMD" ]]; then
                  CMD=$1
              else
                  CMD_ARGS+=("$1")
              fi
              shift
              ;;
      esac
  done

  export DEBUG
  export IS_SYNC
  export CMD
  export CMD_ARGS
  export screenNum
  export args
}
