#!/bin/bash
# shellcheck disable=SC2155
if ! type "include" > /dev/null 2>&1; then
  include() {
    . "$(cd "$(dirname "$1")" && pwd)/${2}";
  };
fi
include "${BASH_SOURCE[0]}" ../pragma_once.bash
if ! pragma_once ${BASH_SOURCE[0]}; then return 0; fi
include "${BASH_SOURCE[0]}" ../base/export.bash
false && source ../base/export.bash




insert_after_match() {
  local file="$1"
  local pattern="$2"
  local insert_content="$3"
  if [[ ! -f "$file" ]]; then
    echo "File not found: $file"
    return 75
  fi
  local tmp="${file}.tmp"
  # 使用 awk 插入（比 sed 更稳） awk 是拓展正则表达式  \(是字面量
  echo "insert_content ${insert_content}"
  awk -v pat="$pattern" -v block="$insert_content" '
    {
        print
        if ($0 ~ pat && inserted != 1) {
            print block
            inserted=1
        }
    }
    END {
        if (inserted == 1)
            exit 0
        else
            exit 100
    }
  ' "$file" >"$tmp"
  rc=$?
  if [[ $rc -eq 0 ]]; then
    mv "$tmp" "$file"
    echo "插入成功！"
    return 0
  else
    rm -f "$tmp"
    echo "插入失败没找到"
    return 76
  fi
}



_collect_files() {
  local path_list="$1"
  local exclude_list="$2"
  local -n out_files="$3"
  local -n out_skipped="$4"

  local paths=()
  local excludes=()
  local path=""
  local file=""
  local ex=""

  out_files=()
  out_skipped=()

  IFS=',' read -ra paths <<< "$path_list"
  IFS=',' read -ra excludes <<< "$exclude_list"

  for path in "${paths[@]}"; do
    [[ -z "$path" ]] && continue

    if [[ -f "$path" ]]; then
      local skip=0
      for ex in "${excludes[@]}"; do
        [[ -z "$ex" ]] && continue

        if [[ "$path" == "$ex" ]] || \
          [[ "$(basename "$path")" == "$ex" ]] || \
          [[ "$path" == $ex ]]; then
          skip=1
          break
        fi

        if [[ -d "$ex" ]]; then
          [[ "$path" == "$ex" || "$path" == "$ex"/* ]] && skip=1 && break
        fi
      done

      if [[ $skip -eq 1 ]]; then
        out_skipped+=("$path")
      else
        out_files+=("$path")
      fi

    elif [[ -d "$path" ]]; then
      while IFS= read -r -d '' file; do

        local skip=0
        for ex in "${excludes[@]}"; do
          [[ -z "$ex" ]] && continue

          if [[ "$file" == "$ex" ]] || \
            [[ "$(basename "$file")" == "$ex" ]] || \
            [[ "$file" == $ex ]]; then
            skip=1
            break
          fi

          if [[ -d "$ex" ]]; then
            [[ "$file" == "$ex" || "$file" == "$ex"/* ]] && skip=1 && break
          fi
        done

        if [[ $skip -eq 1 ]]; then
          out_skipped+=("$file")
        else
          out_files+=("$file")
        fi

      done < <(find "$path" -type f -print0)

    else
      echo "WARNING: path not found, skip: $path"
    fi
  done
}



sed_in_tree() {
  local path_list="$1"
  local search_str="$2"
  local replace_str="$3"
  local exclude_list="$4"

  local files=()
  local skipped=()

  _collect_files "$path_list" "$exclude_list" files skipped

  [[ -z "$search_str" ]] && {
    log_error "search_str is empty"
    return 1
  }

  # ================= sed 替换规则说明 =================
  # sed 替换基本格式：
  #   s<分隔符>pattern<分隔符>replacement<分隔符>flags
  # --------------------------------------------------
  # 一、分隔符（delimiter）
  #
  # - 可以自定义为任意“单个字符”
  # - 常见：/ | # @
  # - 如果分隔符出现在 pattern 或 replacement 中，必须转义
  #
  # 示例：
  #   s|/home/user|/tmp|g     # 推荐（避免转义 /）
  #
  # --------------------------------------------------
  # 二、pattern（左边：正则表达式）
  #
  # 默认是 BRE（基本正则）
  #
  # 特殊字符：
  #   .   任意字符
  #   *   重复
  #   ^   行首
  #   $   行尾
  #   [ ] 字符集合
  #   \   转义符
  #
  # 如果要匹配字面值，需要转义：
  #   a.b   -> a\.b
  #
  # --------------------------------------------------
  # 三、replacement（右边：替换内容）
  #
  # 特殊符号：
  #   &    代表“整个匹配内容”
  #   \1   第1个分组
  #   \2   第2个分组
  #   \    转义符
  #
  # 示例：
  #   s/b/&X/    -> b 变成 bX
  #
  # 如果要替换成字面 &：
  #   \&
  #
  # --------------------------------------------------
  # 四、分隔符冲突
  #
  # 如果你用：
  #   s|xxx|yyy|
  #
  # 那么：
  #   | 出现在内容里必须写成 \|
  #
  # --------------------------------------------------
  # 五、shell 层注意（非常重要）
  #
  # 在 bash 中：
  #   sed "s|$search|$replace|g"
  #
  # 实际有三层解析：
  #   1. shell 变量展开
  #   2. sed pattern（正则）
  #   3. sed replacement（特殊符号）
  #
  # 风险：
  #   - pattern 被当正则（. * 等会生效）
  #   - replacement 中 & 会被替换
  #   - 分隔符冲突导致报错
  #
  # --------------------------------------------------
  # 六、结论
  #
  # - sed 转义符是：\
  # - 左边是正则，右边是替换语法
  # - 分隔符可以自定义，但要避免冲突
  #
  # ==================================================
  printf '%s\0' "${files[@]}" | xargs -0 sed -i "s|${search_str}|${replace_str}|g"
  log_debug "-----------------------------------"
  log_debug "【$search_str】 替换为 【$replace_str】"
  log_debug "Files  : ${#files[@]}"
  log_debug "Files skipped  : ${#skipped[@]}"
}


#gen_pth my.pth \
#  "D:\wyc\env\...\python3.12" \
#  "D:\wyc\env\...\lib-dynload"
gen_python_pth() {
  local pth_file="$1"
  shift

  if [ -z "$pth_file" ] || [ "$#" -eq 0 ]; then
    log_warn "Usage: gen_python_pth <output.pth> <path1> [path2 ...]" >&2
    return 1
  fi

  local pth_dir
  pth_dir="$(cd "$(dirname "$pth_file")" 2>/dev/null && pwd)"
  if [ -z "$pth_dir" ]; then
    log_error "Error: cannot resolve pth file directory: $pth_file" >&2
    return 1
  fi

  local p resolved

  # 先检查，全部通过后再写文件，避免生成半截内容
  for p in "$@"; do
    case "$p" in
    /*|[A-Za-z]:[\\/]*)
    # 绝对路径：Linux /xxx 或 Windows C:\xxx / C:/xxx
      resolved="$p"
      ;;
    *)
    # 相对路径：相对于 .pth 文件所在目录
      resolved="$pth_dir/$p"
      ;;
    esac

    if [ ! -d "$resolved" ]; then
      log_error "Error: directory does not exist: $p" >&2
      log_error "       resolved path: $resolved" >&2
      return 1
    fi
  done

  : > "$pth_file" || {
    log_error "Error: cannot write to $pth_file" >&2
    return 1
  }

  for p in "$@"; do
    echo "$p" >> "$pth_file"
  done

  log_debug "Generated $pth_file"
}


# /ae/bash/gcc/env/win_arm_kylin_930/sysroot/usr/lib/aarch64-linux-gnu/cmake
# sysroot/usr/lib/aarch64-linux-gnu/cmake

patch_system_qt5(){
  local SYSROOT="${1}"
  local CMAKE_DIR="${2}"
  local qt_host_tool_dir="${3}"
  check_directory_var qt_host_tool_dir
  check_file_ex "传入的qt_host_tool_dir不对,不包含必须文件moc.exe" "${qt_host_tool_dir}/moc.exe"

  local dest="${SYSROOT}/usr/lib/qt5/bin"
  check_and_create_dir_var dest
  cp -r "${qt_host_tool_dir}/"* "${dest}"


  check_directory "${SYSROOT}"
  check_directory "${CMAKE_DIR}"
  local CMAKE_CURRENT_LIST_DIR="${CMAKE_DIR}/Qt5"
  check_directory "${CMAKE_CURRENT_LIST_DIR}"
  local exclude_list="${CMAKE_CURRENT_LIST_DIR}/Qt5Config.cmake"




  local Qt5WidgetsConfigExtras="${CMAKE_DIR}/Qt5Widgets/Qt5WidgetsConfigExtras.cmake"
  check_file_var Qt5WidgetsConfigExtras
  sed_in_tree \
    "${Qt5WidgetsConfigExtras}" \
    'bin/uic"' \
    'bin/uic.exe"' \
    ""


  local Qt5CoreConfigExtras="${CMAKE_DIR}/Qt5Core/Qt5CoreConfigExtras.cmake"
  check_file_var Qt5CoreConfigExtras
  sed_in_tree \
    "${Qt5CoreConfigExtras}" \
    'bin/rcc"' \
    'bin/rcc.exe"' \
    ""

  sed_in_tree \
    "${Qt5CoreConfigExtras}" \
    'bin/moc"' \
    'bin/moc.exe"' \
    ""
#
#  sed_in_tree \
#    "${Qt5CoreConfigExtras}" \
#    'bin/qmake"' \
#    'bin/qmake.exe"' \
#    ""


  local QT5_DIR_LIST=""
  for d in "$CMAKE_DIR"/Qt5*; do
    [[ -d "$d" ]] || continue
    QT5_DIR_LIST+="${d},"
  done
  QT5_DIR_LIST="${QT5_DIR_LIST%,}"

  sed_in_tree \
  "${QT5_DIR_LIST}" \
  '"/usr' \
  '"${_psc_sys_root}/usr' \
  "${exclude_list}"


  local rel_path=$(realpath --relative-to="${CMAKE_CURRENT_LIST_DIR}" "${SYSROOT}")
  insert_after_match \
    "${CMAKE_DIR}/Qt5/Qt5Config.cmake" \
    'get_filename_component[(]_qt5_install_prefix.*[)]' \
    "
      if(CMAKE_SYSROOT)
          set(_psc_sys_root \"\${CMAKE_SYSROOT}\")
          message(STATUS \"CMAKE_SYSROOT:psc_sys_root = \${_psc_sys_root} at \${CMAKE_CURRENT_LIST_FILE}  \")
      else()
          set(_psc_sys_root \${CMAKE_CURRENT_LIST_DIR}/${rel_path})
          message(STATUS \"psc_sys_root = \${_psc_sys_root} at \${CMAKE_CURRENT_LIST_FILE} \")
      endif()
    "

  log_info "patch_system_qt end!"
}