#!/bin/bash

# 在7681上执行此脚本，会自动下载lts最新升级包
# curl -sSL --insecure http://ota.wghaos.com/upos | bash -

# 安装指定版本，需要下载本脚本
# wget http://ota.wghaos.com/upos && chmod +x upos
# ./upos 12.3.3 # 安装指定版本升级包
# 或者 curl -sSL --insecure http://ota.wghaos.com/upos | bash -s 12.3.3 # 安装指定版本升级包
# 使用 -f 参数可以跳过版本检查和交互: ./upos -f 12.3.3
# 使用 -r false 参数可以跳过重启提示: ./upos -r false 12.3.3

# 默认参数设置
FORCE_UPGRADE=false
REBOOT_PROMPT=true

# 默认语言设置为英文
LANG_MODE="en"

if [ -f "/etc/proxy/zone" ] && [ "$(cat /etc/proxy/zone)" = "cn" ]; then
  LANG_MODE="cn"
fi

log_info() {
  if [ "$LANG_MODE" = "cn" ]; then
    echo -e "\033[32m[信息]\033[0m $1"
  else
    echo -e "\033[32m[INFO]\033[0m $2"
  fi
}

log_warn() {
  if [ "$LANG_MODE" = "cn" ]; then
    echo -e "\033[33m[警告]\033[0m $1"
  else
    echo -e "\033[33m[WARN]\033[0m $2"
  fi
}

log_error() {
  if [ "$LANG_MODE" = "cn" ]; then
    echo -e "\033[31m[错误]\033[0m $1"
  else
    echo -e "\033[31m[ERROR]\033[0m $2"
  fi
}

log_success() {
  if [ "$LANG_MODE" = "cn" ]; then
    echo -e "\033[32m[成功]\033[0m $1"
  else
    echo -e "\033[32m[SUCCESS]\033[0m $2"
  fi
}

if [ ! -f '/etc/os-release' ]; then
  log_error '找不到os-release文件' 'no such file os-release'
  exit 1
fi

for pkg in jq yq rauc ha; do
  if [ -z "$(command -v $pkg)" ]; then
    log_error "找不到命令 $pkg" "not found command $pkg"
    exit 1
  fi
done

VER_ADDR=https://version.wghaos.com/
TARGET_DIR=/mnt/data

source /etc/os-release

if [ -z "${OS_SUBID}" ]; then
  log_error "找不到OS_SUBID" "not found OS_SUBID"
  exit 0
fi

TZ='UTC-8' date "+%Y/%m/%d %H:%M:%S"

# 获取ZONE信息
ZONE="cn"
if [ -s "/etc/proxy/zone" ]; then
  ZONE=$(cat /etc/proxy/zone)
fi

# 获取SU版本
SU_VERSION=""
if command -v ha >/dev/null; then
  # 尝试使用 --raw-json 获取
  ha_ver=$(ha supervisor info --raw-json < /dev/null 2>/dev/null | jq -r .data.version 2>/dev/null)
  # 如果失败，尝试解析默认输出 (YAML 格式)
  if [ -z "$ha_ver" ] || [ "$ha_ver" == "null" ]; then
    ha_ver=$(ha supervisor info < /dev/null 2>/dev/null | grep '^version:' | awk '{print $2}')
  fi
  if [ -n "$ha_ver" ] && [ "$ha_ver" != "null" ]; then
    SU_VERSION="$ha_ver"
  fi
fi

get_version_info() {
  log_info "正在获取版本信息..." "Getting version info..." >&2
  local version_info=$(curl -sSL --insecure "${VER_ADDR}/${OS_SUBID}-release-${ZONE}.json?os=${VERSION_ID}&su=${SU_VERSION}")
  
  if [ -z "$version_info" ] || [ "$version_info" = "null" ] || [[ "$version_info" == *"<html>"* ]]; then
    log_error "无法获取版本信息，请检查网络连接" "Cannot get version info, please check network connection" >&2
    exit 1
  fi
  
  echo "$version_info"
}

# 获取版本信息
version_info=$(get_version_info)
if [ -z "$version_info" ]; then
  log_error "无法获取版本信息" "Cannot get version info" >&2
  exit 1
fi

# 获取当前版本的主版本号
get_major_version() {
  echo "$1" | cut -d'.' -f1
}

# 获取推荐的升级版本
get_recommended_version() {
  local current_version="$1"
  local major_version=$(get_major_version "$current_version")
  
  local has_key=$(echo "$version_info" | yq -r ".hassos-upgrade | has(\"$major_version\")")
  
  if [ "$has_key" = "true" ]; then
    local recommended_version=$(echo "$version_info" | yq -r ".hassos-upgrade | .[\"$major_version\"]")
    
    if [ "$recommended_version" != "null" ] && [ -n "$recommended_version" ]; then
      echo "$recommended_version"
      return
    fi
  fi
  
  echo "$current_version"
}

# 获取最新可用版本
get_latest_version() {
  echo "$version_info" | yq ".hassos.${OS_SUBID}"
}

# 解析命令行参数
while getopts "fr:" opt; do
  case $opt in
    f)
      FORCE_UPGRADE=true
      ;;
    r)
      if [ "$OPTARG" = "false" ]; then
        REBOOT_PROMPT=false
      fi
      ;;
    \?)
      log_error "无效的选项: -$OPTARG" "Invalid option: -$OPTARG"
      exit 1
      ;;
  esac
done

# 移动参数位置，使得 $1 成为第一个非选项参数
shift $((OPTIND-1))

cus_ver=$1
if [ -z "$cus_ver" ]; then
  # 获取当前版本的推荐升级版本
  recommended_version=$(get_recommended_version "$VERSION_ID")
  latest_version=$(get_latest_version)
  
  # 比较当前版本与推荐版本
  if [[ "$VERSION_ID" < "$recommended_version" ]]; then
    log_warn "您的HAOS版本需要先升级到 $recommended_version 才能继续升级到最新版本" "Your HAOS version needs to be upgraded to $recommended_version before upgrading to the latest version"
    log_info "正在准备升级到版本 $recommended_version" "Preparing to upgrade to version $recommended_version"
    ver="$recommended_version"
  elif [[ "$VERSION_ID" < "$latest_version" ]]; then
    log_info "您的HAOS版本可以直接升级到最新版本 $latest_version" "Your HAOS version can be upgraded directly to the latest version $latest_version"
    ver="$latest_version"
  else
    ver=${VERSION_ID}
    log_success "您的系统版本已经是最新版本 ${VERSION_ID}" "Your OS version is already the latest ${VERSION_ID}"
    if [ "$FORCE_UPGRADE" == "true" ]; then
      log_info "将覆盖安装最新版本(${ver})" "Will force upgrade latest version ${ver}"
    else
      exit 0
    fi
  fi
else
  ver="$cus_ver"
fi

# 版本比较函数，用于比较两个版本号的大小
version_compare() {
  if [[ "$1" == "$2" ]]; then
    echo "equal"
  elif [[ $(echo -e "$1\n$2" | sort -V | head -n1) == "$1" ]]; then
    echo "less"
  else
    echo "greater"
  fi
}

# 检查当前版本是否已经是目标版本（除非强制升级）
if [ "$FORCE_UPGRADE" != "true" ]; then
  version_status=$(version_compare "${VERSION_ID}" "${ver}")
  if [ "$version_status" == "equal" ]; then
    log_success "您的系统版本已经是 ${ver}" "Your OS version is already ${ver}"
    exit 0
  elif [ "$version_status" == "greater" ]; then
    log_warn "您的系统版本 ${VERSION_ID} 高于目标版本 ${ver}，不需要降级" "Your OS version ${VERSION_ID} is higher than the target version ${ver}, no need to downgrade"
    exit 0
  fi
fi

ota=$(echo "$version_info" | jq -r '.ota')
raucb_addr=$(echo "${ota}" | sed "s#/{board}#/${OS_SUBID}#;s#_{board}#_${OS_SUBID}#;s#{os_name}#${ID}#g;s#{version}#${ver}#g")

# 检查OTA文件是否存在，处理可能的SSL证书问题
check_ota_file() {
  local url="$1"
  
  # 直接使用--insecure选项绕过SSL验证
  local curl_output=$(curl -sIL --insecure -w "%{http_code}\n" -o /dev/null "$url")
  
  # 检查HTTP状态码
  if [[ "$curl_output" == 200 ]]; then
    log_success "成功验证OTA文件存在" "Successfully verified OTA file exists" >&2
    return 0
  else
    log_error "OTA文件不存在或无法访问，HTTP状态码: $curl_output" "OTA file does not exist or cannot be accessed, HTTP status code: $curl_output" >&2
    return 1
  fi
}

# 检查OTA文件是否存在
if ! check_ota_file "${raucb_addr}"; then
  log_error "在 ${raucb_addr} 找不到OTA文件" "OTA file not found at ${raucb_addr}"
  exit 1
fi

filename=$(basename "${raucb_addr}")

# 检查本地文件是否已存在
if [ -s "${TARGET_DIR}/${filename}" ]; then
  log_info "本地已存在升级包文件 ${filename}，将直接使用" "Local upgrade package ${filename} already exists, will use it directly"
  log_info "如需重新下载，请先删除文件: rm ${TARGET_DIR}/${filename}" "To download again, please delete the file first: rm ${TARGET_DIR}/${filename}"
else
  log_info "正在下载升级包..." "Downloading upgrade package..."
  
  # 下载OTA文件，处理可能的SSL证书问题
  download_ota_file() {
    local url="$1"
    local output_file="$2"
    
    log_info "开始下载OTA文件: $url" "Start downloading OTA file: $url" >&2
    
    # 先尝试使用curl下载（带--insecure选项）
    curl -L --insecure -o "$output_file" "$url"
    
    # 如果curl失败，尝试使用wget
    if [ $? -ne 0 ]; then
      log_warn "curl下载失败，尝试使用wget" "curl download failed, trying wget" >&2
      wget --no-check-certificate -q -O "$output_file" "$url"
      if [ $? -ne 0 ]; then
        log_error "下载OTA文件失败" "Failed to download OTA file" >&2
        return 1
      else
        log_success "使用wget成功下载OTA文件" "Successfully downloaded OTA file using wget" >&2
      fi
    else
      log_success "成功下载OTA文件" "Successfully downloaded OTA file" >&2
    fi
    
    return 0
  }
  
  # 尝试下载OTA文件
  if ! download_ota_file "${raucb_addr}" "${TARGET_DIR}/${filename}"; then
    # 如果curl下载失败，尝试使用wget作为备选
    log_warn "使用curl下载失败，尝试使用wget下载" "Failed to download with curl, trying with wget" >&2
    wget --no-check-certificate -O "${TARGET_DIR}/${filename}" "${raucb_addr}"
  fi
  
  if [ ! -s "${TARGET_DIR}/${filename}" ]; then
    log_error "检查raucb文件出错" "Error checking raucb file"
    exit 1
  fi
fi

log_info "正在安装升级包..." "Installing upgrade package..."
install_output=$(rauc install "${TARGET_DIR}/$filename" 2>&1)
install_status=$?

if [ $install_status -eq 0 ]; then
  log_success "安装完成" "Installation completed"
  rm "${TARGET_DIR}/${filename}"
  
  check_further_upgrade() {
    local installed_ver="$ver"
    local latest_ver=$(get_latest_version)
    
    if [[ "$installed_ver" < "$latest_ver" ]]; then
      local major_ver=$(get_major_version "$installed_ver")
      local next_major=$((major_ver + 1))
      
      local has_key=$(echo "$version_info" | yq -r ".hassos-upgrade | has(\"$next_major\")")
      local next_recommended=""
      
      if [ "$has_key" = "true" ]; then
        next_recommended=$(echo "$version_info" | yq -r ".hassos-upgrade | .[\"$next_major\"]")
      else
        next_recommended=$latest_ver
      fi
      
      if [ "$next_recommended" != "null" ] && [ -n "$next_recommended" ]; then
        log_info "当前版本 $installed_ver 安装完成，系统重启后可继续升级到 $next_recommended" "Current version $installed_ver installed, after reboot you can upgrade to $next_recommended"
        log_info "重启后请再次运行升级脚本" "Please run the upgrade script again after reboot"
      fi
    else
      log_success "已升级到最新版本 $installed_ver" "Upgraded to the latest version $installed_ver"
    fi
  }
  
  check_further_upgrade

  # 根据REBOOT_PROMPT参数决定是否提示重启
  if [ "$REBOOT_PROMPT" != "true" ]; then
    log_info "升级完成，无需重启" "Upgrade completed, no reboot required"
    exit 0
  fi
  # 仅命令行下执行重启交互
  if [ -t 1 ]; then
    read -p "$([ "$LANG_MODE" = "cn" ] && echo "是否立即重启系统? (y/n): " || echo "Reboot system now? (y/n): ")" answer < /dev/tty
    case "$(echo $answer | tr '[:upper:]' '[:lower:]')" in
        y|yes)
        log_info "正在重启系统..." "Rebooting system..."
        ha host reboot || {
            reboot || {
            log_warn "重启命令执行失败，请手动重启系统" "Reboot command failed, please reboot manually"
            log_info "请稍后手动重启系统: ha host reboot" "Please reboot manually later: ha host reboot"
            }
        }
        ;;
        *)
        log_info "请稍后手动重启系统: ha host reboot" "Please reboot manually later: ha host reboot"
        ;;
    esac
  else
    log_info "请稍后手动重启系统: ha host reboot" "Please reboot manually later: ha host reboot"
  fi
else
  log_error "安装失败，错误信息: $install_output" "Installation failed, error: $install_output"
fi


