#!/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



# 必选项
export bge_install_prefix
# 平台选项
export bge_build bge_host bge_target
export bge_source_sysroot   #   交叉编译和 拿大编译必填项  使用模式两种  软链接使用和  复制使用
export bge_sysroot_use_mode #   使用模式两种  软链接(link), 复制(copy) 使用

# 1阶段gcc
export bge_stage1 #   1代表这是不依赖glibc的gcc，用于构建glibc的gcc，0代表是普通的gcc

# url选项集合
export bge_gcc_ver bge_gcc_suffix_opts
export bge_gmp_url bge_gmp_suffix_opts
export bge_mpfr_url bge_mpfr_suffix_opts
export bge_mpc_url bge_mpc_suffix_opts
export bge_binutils_gdb_ver bge_binutils_gdb_suffix_opts
export bge_isl_url bge_isl_suffix_opts

# 内部自动计算的变量(每次都会刷新)
export bge_build_mode # native pseudo_native  cross canadian_stage3
export b_cpu b_vendor b_os b_abi
export h_cpu h_vendor h_os h_abi
export t_cpu t_vendor t_os t_abi

export bge_toolchain_name


bge_dump_config() {
  log_info "========== 【构建gcc 全局选项 BGE CONFIG】 =========="

  log_info "%-24s = %s" "bge_install_prefix" "${bge_install_prefix}"

  log_info "%-24s = %s" "bge_build" "${bge_build}"
  log_info "%-24s = %s" "bge_host" "${bge_host}"
  log_info "%-24s = %s" "bge_target" "${bge_target}"
  log_info "%-24s = %s" "bge_build_mode" "${bge_build_mode}"

  log_info "%-24s = %s" "bge_source_sysroot" "${bge_source_sysroot}"
  log_info "%-24s = %s" "bge_sysroot_use_mode" "${bge_sysroot_use_mode}"

  log_info "内部自动计算的变量"
  parse_triplet "$bge_build" b_cpu b_vendor b_os b_abi
  parse_triplet "$bge_host" h_cpu h_vendor h_os h_abi
  parse_triplet "$bge_target" t_cpu t_vendor t_os t_abi
  log_info "bge_build_mode:%s" "${bge_build_mode}"
  log_info "%-24s = cpu=%-12s vendor=%-12s os=%-12s abi=%s" "build tuple"  "$b_cpu" "$b_vendor" "$b_os" "$b_abi"
  log_info "%-24s = cpu=%-12s vendor=%-12s os=%-12s abi=%s" "host tuple"   "$h_cpu" "$h_vendor" "$h_os" "$h_abi"
  log_info "%-24s = cpu=%-12s vendor=%-12s os=%-12s abi=%s" "target tuple" "$t_cpu" "$t_vendor" "$t_os" "$t_abi"



  log_info "每次build_gcc后需要，手动重置的变量"
  log_info "%-24s = %s" "bge_gcc_ver" "${bge_gcc_ver}"
  log_info "%-24s = %s" "bge_gcc_suffix_opts" "${bge_gcc_suffix_opts}"
  log_info "%-24s = %s" "bge_gmp_url" "${bge_gmp_url}"
  log_info "%-24s = %s" "bge_gmp_suffix_opts" "${bge_gmp_suffix_opts}"
  log_info "%-24s = %s" "bge_mpfr_url" "${bge_mpfr_url}"
  log_info "%-24s = %s" "bge_mpfr_suffix_opts" "${bge_mpfr_suffix_opts}"
  log_info "%-24s = %s" "bge_mpc_url" "${bge_mpc_url}"
  log_info "%-24s = %s" "bge_mpc_suffix_opts" "${bge_mpc_suffix_opts}"
  log_info "%-24s = %s" "bge_isl_url" "${bge_isl_url}"
  log_info "%-24s = %s" "bge_isl_suffix_opts" "${bge_isl_suffix_opts}"
  log_info "%-24s = %s" "bge_binutils_gdb_ver" "${bge_binutils_gdb_ver}"
  log_info "%-24s = %s" "bge_binutils_gdb_suffix_opts" "${bge_binutils_gdb_suffix_opts}"



  log_info "%-24s = %s" "bge_toolchain_name" "${bge_toolchain_name}"

  log_info "========== 【构建gcc 全局选项 BGE CONFIG】 =========="
}

bge_refresh_ver(){
  bge_gcc_ver="releases/gcc-15.1.0"
  bge_gcc_suffix_opts=""
  bge_gmp_url="https://mirrors.tuna.tsinghua.edu.cn/gnu/gmp/gmp-6.2.0.tar.xz"
  bge_gmp_suffix_opts=""
  bge_mpfr_url="https://mirrors.tuna.tsinghua.edu.cn/gnu/mpfr/mpfr-4.2.2.tar.xz"
  bge_mpfr_suffix_opts=""
  bge_mpc_url="https://mirrors.tuna.tsinghua.edu.cn/gnu/mpc/mpc-1.3.1.tar.gz"
  bge_mpc_suffix_opts=""
  bge_isl_url="https://libisl.sourceforge.io/isl-0.26.tar.xz"
  bge_isl_suffix_opts=""
  bge_binutils_gdb_ver="binutils-2_46"
  bge_binutils_gdb_suffix_opts=""
}

bge_init_params() {
  # 必选项
  bge_install_prefix="/ae/env/local_gcc_15_1_0"
  # 平台选项
  local local_triplet
  detect_platform_triplet local_triplet local_triplet_no_vendor
  bge_build="${local_triplet}"
  bge_host="${local_triplet}"
  bge_target="${local_triplet}"
  bge_source_sysroot=""
  bge_sysroot_use_mode="link"
  # 1阶段gcc
  bge_stage1=0
  # url选项集合
  bge_refresh_ver
}
# 初始化参数值
bge_init_params

bge_check_params() {
  bge_dump_config
  [[ -z "$bge_build" || -z "$bge_host" || -z "$bge_target" ]] && log_error "ERROR:build/host/target not fully set" && exit 1
  log_info "原始 build:$bge_build host:$bge_host target:$bge_target"
  check_value_in_range bge_sysroot_use_mode "link" "copy"
  check_value_in_range bge_stage1 "1" "0"



  local b_full="${b_cpu}-${b_vendor}-${b_os}-${b_abi}"
  local h_full="${h_cpu}-${h_vendor}-${h_os}-${h_abi}"
  local t_full="${t_cpu}-${t_vendor}-${t_os}-${t_abi}"

  local b_core="${b_cpu}_${b_os}_${b_abi}"
  local h_core="${h_cpu}_${h_os}_${h_abi}"
  local t_core="${t_cpu}_${t_os}_${t_abi}"

  log_info "核心 build:$b_core host:$h_core target:$t_core"

  if [[ "$b_full" == "$h_full" && "$h_full" == "$t_full" ]]; then
    bge_build_mode="native"

  elif [[ "$b_core" == "$h_core" && "$h_core" == "$t_core" ]]; then
    bge_build_mode="pseudo_native"

  elif [[ "$b_full" == "$h_full" ]]; then
    bge_build_mode="cross"
  else
    bge_build_mode="canadian_stage3"
  fi
  #  check_and_create_dir "$bge_source_sysroot"
  if [[ "$bge_build_mode" == "cross" ||
    "$bge_build_mode" == "canadian_stage3" ]]; then
    [[ "$bge_sysroot_use_mode" != "link" && "$bge_sysroot_use_mode" != "copy" ]] && log_error "ERROR:invalid bge_sysroot_use_mode:$bge_sysroot_use_mode" && exit 5
  fi
  log_info "$bge_build_mode check ok!"
}


# sudo apt install flex bison   git依赖
build_gcc_ex() {
  bge_check_params
  local sysroot=""

  if [[ "$bge_build_mode" == "cross" ||
    "$bge_build_mode" == "canadian_stage3" ]]; then
    local base="${bge_install_prefix}/${bge_target}"
    sysroot="${base}/sysroot"
    exec_record_fast_fail "rm -rf \"${sysroot}\""
    exec_record_fast_fail "mkdir -p \"$(dirname "${sysroot}")\""
    if [[ "$bge_sysroot_use_mode" == "link" ]]; then
      local relative_path
      relative_path=$(realpath --relative-to="$(dirname "${sysroot}")" "${bge_source_sysroot}")
      log_info "sysroot: ${sysroot}  bge_source_sysroot:${bge_source_sysroot}  relative_path:${relative_path}"
      exec_record_fast_fail "ln -s \"${relative_path}\" \"${sysroot}\""
    elif [[ "$bge_sysroot_use_mode" == "copy" ]]; then
      exec_record_fast_fail "mkdir -p \"${sysroot}\""
      exec_record_fast_fail "cp -a \"${bge_source_sysroot}/.\" \"${sysroot}/\""
    fi
  fi
  if [[ "$bge_build_mode" == "pseudo_native" ]]; then
    sysroot="/"
  fi




  (
    #GMP（大整数库）在 MinGW/Windows host 场景下的一个明确限制：
    # 在同一次构建里同时启用 --enable-shared 和 --enable-static，
    # 会导致生成的 gmp.h 内容不一致（静态库和 DLL 的 gmp.h 有不同的导出宏/声明），
    # 所以 configure 直接拒绝
    local build_host="--build=$bge_build --host=$bge_host"
    local prefix_opt="--prefix=$bge_install_prefix"
    #local lib_opts="--disable-static --enable-shared"
    local lib_opts="--enable-static --disable-shared"

    configure_gnu_zip "$bge_gmp_url" "$prefix_opt $build_host $lib_opts $bge_gmp_suffix_opts"
    exec_record_fast_fail "make -j $(nproc)"
    exec_record_fast_fail "make install-strip -j $(nproc)"

    configure_gnu_zip "$bge_mpfr_url" "$prefix_opt $build_host --with-gmp=$bge_install_prefix $lib_opts $bge_mpfr_suffix_opts"
    exec_record_fast_fail "make -j $(nproc)"
    exec_record_fast_fail "make install-strip -j $(nproc)"

    configure_gnu_zip  "$bge_mpc_url" "$prefix_opt $build_host --with-gmp=$bge_install_prefix --with-mpfr=$bge_install_prefix $lib_opts $bge_mpc_suffix_opts"
    exec_record_fast_fail "make -j $(nproc)"
    exec_record_fast_fail "make install-strip -j $(nproc)"


    configure_gnu_zip  "$bge_isl_url" "$prefix_opt $build_host --with-gmp-prefix=$bge_install_prefix  $lib_opts $bge_isl_suffix_opts"
    exec_record_fast_fail "make -j $(nproc)"
    exec_record_fast_fail "make install-strip -j $(nproc)"

    #  --disable-doc 或者 apt install texinfo
    local binutils_opts
    binutils_opts="$prefix_opt --build=$bge_build --host=$bge_host --target=$bge_target  \
    --with-gmp=$bge_install_prefix --with-mpfr=$bge_install_prefix --with-mpc=$bge_install_prefix --with-isl=$bge_install_prefix  \
    --disable-doc --disable-werror  --disable-nls"
    if [[
      "$bge_build_mode" == "cross" ||
      "$bge_build_mode" == "canadian_stage3" ]] \
      ; then
      local ld_search_path="=/lib:=/lib64:=/usr/lib:=/usr/lib64:=/lib/${bge_target}:=/usr/lib/${bge_target}"
      # 这里=会在后续的链接器选项中变成sysroot
      binutils_opts="${binutils_opts} --with-sysroot=$sysroot --with-lib-path=${ld_search_path}"
    fi

    if [[ "$bge_build_mode" == "pseudo_native" ]]; then
      binutils_opts="${binutils_opts} --with-sysroot=$sysroot"
    fi



    binutils_opts="${binutils_opts}  $bge_binutils_gdb_suffix_opts"
#    configure_gnu_zip "$bge_binutils_url" "$binutils_opts"


    local src_dir
    ensure_repo_version src_dir "binutils-gdb" "$bge_binutils_gdb_ver"
    configure_gnu "${src_dir}" "$binutils_opts"
    exec_record_fast_fail "make -j $(nproc)"
    exec_record_fast_fail "make install-strip -j $(nproc)"
  )



#  --disable-multiarch \ 怎么确定sysroot是不是 multiarch 布局
  check_ret_exit "构建gcc_rely_${bge_build_mode}失败!"
  (
    # 这里不能加" 加了的话 eval 执行不对了  寻找匹配的“"”时遇到了未预期的文件结束符
    local gcc_opts=" \
    --prefix=$bge_install_prefix \
    --build=$bge_build --host=$bge_host --target=$bge_target \
    --with-gmp=$bge_install_prefix \
    --with-mpfr=$bge_install_prefix \
    --with-mpc=$bge_install_prefix \
    --with-isl=$bge_install_prefix \
  "
#    if [[ "${h_os}" == "w64"  ]]; then
#      local exe_dir="${bge_install_prefix}/bin"
#      gcc_opts="\
#      --libexecdir=\"${exe_dir}/\" \
#      ${gcc_opts}"
#      log_info "w64 添加库到exe所在目录, 这样不用配置环境变量"
#    fi

    if [[ "$bge_stage1" == "0" ]]; then
      log_info "构建普通gcc，依赖glibc"
      gcc_opts="\
            --disable-multilib \
            --enable-languages=c,c++ \
            --enable-shared \
            --enable-static \
            --disable-werror \
            --disable-bootstrap \
            --disable-libsanitizer  \
            --disable-libssp \
      ${gcc_opts}"
    fi

    if [[ "$bge_stage1" == "1" ]]; then
      log_info "stage1 gcc（不依赖 glibc，用于构建 glibc）"
      # --enable-shared 这个选项开启 会导致 stage1 链接glibc 所以要关掉
      gcc_opts="\
            --with-newlib \
            --without-headers \
            --without-isl \
            --enable-initfini-array \
            --disable-nls \
            --disable-shared \
            --enable-static \
            --disable-multilib \
            --disable-decimal-float \
            --disable-threads \
            --disable-libatomic \
            --disable-libgomp \
            --disable-libquadmath \
            --disable-libssp \
            --disable-libvtv \
            --disable-libstdcxx \
            --disable-bootstrap \
            --enable-languages=c,c++  \
      ${gcc_opts}"
    fi

    if [[ "$bge_build_mode" == "cross" ||
      "$bge_build_mode" == "canadian_stage3" ]]; then
      gcc_opts="--with-sysroot=$sysroot ${gcc_opts}"
    fi
    if [[ "$bge_build_mode" == "pseudo_native" ]]; then
      #   --with-native-system-header-dir=/usr/include
      gcc_opts="--with-sysroot=${sysroot} ${gcc_opts}"
    fi
    gcc_opts="${gcc_opts} ${bge_gcc_suffix_opts}"

    local src_dir
    ensure_repo_version src_dir "gcc" "$bge_gcc_ver"
    exec_record "rm -rf \"${src_dir}/build\""
    cd "${src_dir}" || exit


    # 如果启用了这个选项 共有依赖项就会全部失效
    #exec_record "./contrib/download_prerequisites"
    #export LD_LIBRARY_PATH="${bge_install_prefix}/lib:$LD_LIBRARY_PATH"
    configure_gnu "${src_dir}" "$gcc_opts"

    if [[ "$bge_stage1" == "0" ]]; then
      exec_record_fast_fail "make -j $(nproc)"
      #exec_record_fast_fail "make install  -j $(nproc)"
      exec_record_fast_fail "make install-strip -j $(nproc)"
    fi

    if [[ "$bge_stage1" == "1" ]]; then
      exec_record_fast_fail "make all-gcc -j $(nproc)"
      exec_record_fast_fail "make install-gcc -j $(nproc)"
      exec_record_fast_fail "make all-target-libgcc -j $(nproc)"
      exec_record_fast_fail "make install-target-libgcc -j $(nproc)"
    fi
  )
  check_ret_exit "构建gcc_${bge_build_mode}失败!"

  # 创建 cc c++ 软链接, gcc 安装一般不会附带 但是发行版会自己附带来兼容
  local gcc_bin="${bge_install_prefix}/bin"
  cd "${gcc_bin}"
  ln -sf "${bge_target}-gcc" cc
  ln -sf "${bge_target}-g++" c++


  # 生成cmake 工具链文件
  local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  local template="${SCRIPT_DIR}/cmake_template/toolchain_template.cmake"


  local cmake_os=""
  local cmake_cpu=""
  gnu_os_to_cmake_system_name "$t_os" cmake_os
  gnu_cpu_to_cmake_system_processor "$t_cpu" cmake_cpu
  log_debug "cmake OS  -> $cmake_os"
  log_debug "cmake CPU -> $cmake_cpu"


  local exe shared static prefix
  gnu_triple_to_suffixes ${bge_host} exe shared static prefix


  template_render_to_file_strict  "${template}" "${bge_install_prefix}/${bge_toolchain_name}.cmake" \
    CMAKE_SYSTEM_NAME "${cmake_os}" \
    CMAKE_SYSTEM_PROCESSOR "${cmake_cpu}" \
    exe_suffix "${exe}" \
    build "${bge_build}" \
    host "${bge_host}" \
    target "${bge_target}"



  local preset_template="${SCRIPT_DIR}/cmake_template/toolchain_template.json"
  template_render_to_file_strict  "${preset_template}" "${bge_install_prefix}/preset.json" \
    toolchain_name "${bge_toolchain_name}"
}

#https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-15.1.0/gcc-15.1.0.tar.xz
#"15.1.0"

upgrade_local_gcc() {
  local ver="$1"
  local vendor="$2" # 空字符串就是local_triplet

  [[ -z "$ver" ]] && log_error "ERROR:ver required" && exit 1
  [[ -z "$_root_" ]] && log_error "ERROR:_root_ not set" && exit 2

  local local_triplet local_triplet_no_vendor
  detect_platform_triplet local_triplet local_triplet_no_vendor

  local new_triplet
  if [[ -z "$vendor" ]]; then
    new_triplet="$local_triplet"
  else
    local local_cpu local_vendor local_os local_abi
    parse_triplet "$local_triplet" local_cpu local_vendor local_os local_abi
    compose_triplet new_triplet "$local_cpu" "$vendor" "$local_os" "$local_abi"
  fi
  local install_prefix="/ae/toolchain/${new_triplet}"
  bge_install_prefix="${install_prefix}/$ver"

  log_info "bge_install_prefix $bge_install_prefix"


  bge_gcc_ver="${ver}"
  bge_build="$local_triplet"
  bge_host="$local_triplet"
  bge_target="$new_triplet"
  bge_source_sysroot=""
  bge_sysroot_use_mode="link"
  build_gcc_ex
}

build_local_local_cross_gcc() {
  local target="$1"
  local ver="$2"
  local source_sysroot="$3"

  [[ -z "$target" ]] && log_error "ERROR: target required" && exit 1
  [[ -z "$ver" ]] && log_error "ERROR: ver required" && exit 1
  [[ -z "$source_sysroot" ]] && log_error "ERROR: source_sysroot required" && exit 1
  [[ ! -d "$source_sysroot" ]] && log_error "ERROR: sysroot not found: $source_sysroot" && exit 1
  [[ -z "$_root_" ]] && log_error "ERROR:_root_ not set" && exit 2
  (
    local local_triplet local_triplet_no_vendor
    detect_platform_triplet local_triplet local_triplet_no_vendor

    local install_prefix="$_root_/gcc/${target}"
    bge_install_prefix="${install_prefix}_$ver"

    bge_build="$local_triplet"
    bge_host="$local_triplet"
    bge_target="$target"

    bge_source_sysroot="$source_sysroot"
    bge_sysroot_use_mode="copy"


    bge_gcc_ver="${ver}"
    #bge_gcc_ver="https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-$ver/gcc-$ver.tar.xz"
    build_gcc_ex
  )
  check_ret_exit "build_local_local_cross_gcc 编译错误！"

}


return 0

