#!/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]}" ./global_rely/export.bash
# shellcheck source=./global_rely/export.bash



# 目前只是使用第一个url
get_git_urls() {
  local dep="$1"
  local -n out_urls="$2"
  case "$dep" in
  gmp)
    out_urls=(
      # 这个需要登陆？没法注册
      "https://gitlab.inria.fr/gmp/gmp.git"
    )
    ;;
  mpfr)
    out_urls=(
      "https://gitlab.inria.fr/mpfr/mpfr.git"
    )
    ;;
  mpc)
    out_urls=(
      "https://gitlab.inria.fr/mpc/mpc.git"
    )
    ;;
  llvm-project)
    out_urls=(
      "https://github.com/llvm/llvm-project"
      "https://gitee.com/mirrors/llvm-project.git"
    )
    ;;
  linux)
    out_urls=(
      "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"
      "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"
      "https://mirrors.tuna.tsinghua.edu.cn/git/linux.git"

    )
    ;;
  glibc)
    out_urls=(
      "https://sourceware.org/git/glibc.git"
      "https://mirrors.tuna.tsinghua.edu.cn/git/glibc.git"
    )
    ;;
  newlib-cygwin)
    out_urls=(
      "https://github.com/mirror/newlib-cygwin.git"
    )
    ;;
  mingw-w64)
    out_urls=(
      "https://github.com/mingw-w64/mingw-w64.git"
      "https://mirrors.tuna.tsinghua.edu.cn/git/mingw-w64.git"
      "https://git.code.sf.net/p/mingw-w64/mingw-w64"
    )
    ;;
  zlib)
    out_urls=(
      "https://github.com/madler/zlib.git"
      "https://gitee.com/mirrors/zlib.git"
    )
    ;;
  libxml2)
    out_urls=(
      "https://gitlab.gnome.org/GNOME/libxml2.git"
      "https://gitee.com/mirrors/libxml2.git"
    )
    ;;
  musl)
    out_urls=(
      "https://git.musl-libc.org/git/musl"
    )
    ;;
  binutils-gdb)
    out_urls=(
      "https://sourceware.org/git/binutils-gdb.git"
      "https://mirrors.tuna.tsinghua.edu.cn/git/binutils-gdb.git"
    )
    ;;
  gcc)
    out_urls=(
      "https://gcc.gnu.org/git/gcc.git"
      "https://gitee.com/mirrors/gcc.git"
    )
    ;;
  windows-msvc-sysroot)
    out_urls=(
      "https://github.com/trcrsired/windows-msvc-sysroot.git"
    )
    ;;
  cppwinrt)
    out_urls=(
      "https://github.com/microsoft/cppwinrt.git"
      "https://gitee.com/qabeowjbtkwb/cppwinrt.git"
    )
    ;;
  Qt)
    out_urls=(
      "https://github.com/qt/qt5.git"
    )
    ;;
  cpython)
    out_urls=(
      "https://github.com/python/cpython.git"
    )
    ;;
  cef)
    out_urls=(
      "https://github.com/chromiumembedded/cef.git"
    )
    ;;
  *)
    log_error "未知依赖：${dep}"
    return 1
    ;;
  esac
}
get_repo_refs_local() {
  local repo_dir="$1"
  local -n out_branches="$2"
  local -n out_tags="$3"
  if [[ ! -d "${repo_dir}/.git" ]]; then
    log_error "不是 git 仓库: ${repo_dir}"
    return 1
  fi
  pushd "$repo_dir" >/dev/null || return 1
  mapfile -t out_branches < <(
    git branch --format='%(refname:short)'
  )
  mapfile -t out_tags < <(
    git tag --sort=-version:refname
  )
  popd >/dev/null
}
get_repo_refs_remote() {
  local repo_url="$1"
  local -n out_branches="$2"
  local -n out_tags="$3"
  if [[ -z "$repo_url" ]]; then
    log_error "repo_url 为空"
    return 1
  fi
  mapfile -t out_branches < <(
    git ls-remote --heads "$repo_url" |
      awk '{print $2}' |
      sed 's#refs/heads/##'
  )
  mapfile -t out_tags < <(
    git ls-remote --tags "$repo_url" |
      grep -v '\^{}' |
      awk '{print $2}' |
      sed 's#refs/tags/##'
  )
}
repo_has_ver_local() {
  local repo_dir="$1"
  local ver="$2"

  local branches=()
  local tags=()

  get_repo_refs_local "$repo_dir" branches tags || return 1

  for b in "${branches[@]}"; do
    [[ "$b" == "$ver" ]] && return 0
  done

  for t in "${tags[@]}"; do
    [[ "$t" == "$ver" ]] && return 0
  done

  return 1
}
repo_has_ver_remote() {
  local repo_url="$1"
  local ver="$2"

  local branches=()
  local tags=()

  get_repo_refs_remote "$repo_url" branches tags || return 1

  for b in "${branches[@]}"; do
    [[ "$b" == "$ver" ]] && return 0
  done

  for t in "${tags[@]}"; do
    [[ "$t" == "$ver" ]] && return 0
  done

  return 1
}
print_repo_refs_local() {
  local repo_dir="${1:-.}"
  log_info "========== 本地仓库信息 =========="
  log_info "路径: 【${repo_dir}】"
  if [[ ! -d "${repo_dir}/.git" ]]; then
    log_error "不是 git 仓库"
    return 1
  fi
  pushd "$repo_dir" >/dev/null || return 1
  log_info "\n当前 HEAD:"
  git rev-parse --short HEAD
  log_info "\n当前分支:"
  git branch --show-current
  popd >/dev/null
  local branches=()
  local tags=()
  get_repo_refs_local "$repo_dir" branches tags
  log_info "本地 Branch:"
  printf '%s' "${branches[@]:0:20}"
  log_info "Tag 列表:"
  printf '%s' "${tags[@]:0:20}"
  log_info "远端地址:"
  git -C "$repo_dir" remote -v
}


print_array_in_columns() {
  local -n arr_ref="$1"
  local cols="${2:-3}"

  if ((cols < 1)); then
    cols=1
  fi

  local count="${#arr_ref[@]}"
  if ((count == 0)); then
    printf '无\n'
    return 0
  fi

  local max_width=0
  local item
  for item in "${arr_ref[@]}"; do
    if ((${#item} > max_width)); then
      max_width="${#item}"
    fi
  done

  local cell_width=$((max_width + 2))
  local rows=$(((count + cols - 1) / cols))
  local r c idx

  for ((r = 0; r < rows; r++)); do
    for ((c = 0; c < cols; c++)); do
      idx=$((c * rows + r))
      if ((idx < count)); then
        printf "%-*s" "$cell_width" "${arr_ref[idx]}"
      fi
    done
    printf '\n'
  done
}


print_repo_refs_remote() {
  local repo_url="$1"
  local cols="${2:-4}"

  log_info "========== 远端仓库信息 =========="
  log_info "URL: 【$repo_url】"

  local branches=()
  local tags=()

  get_repo_refs_remote "$repo_url" branches tags || return 1

  log_info "远端 Branch:"
  print_array_in_columns branches "$cols"

  log_info "远端 Tag:"
  print_array_in_columns tags "$cols"
}



get_latest_git_tag() {
  local repo_url="$1"
  git ls-remote --tags "$repo_url" |
    grep -v '\^{}' |
    awk '{print $2}' |
    sed 's#refs/tags/##' |
    sort -V |
    tail -n 1
}
export use_network=1
# ver 指的是 git 的 branch 或者 tag


ensure_repo_version() {
  local -n repo_dir=$1
  local dep="$2"
  local ver="$3"
  repo_dir="${_git_cache_dir_}/${dep}"
  local urls=()

  log_info "ensure_repo_version  ${dep}  ${ver}"
  get_git_urls "$dep" urls || return 1
  local repo_url="${urls[0]}"
  # CHECK_REPO


  # CHECK_LOCAL
  log_info "检查是否需要克隆"
  if [[ ! -d "$repo_dir/.git" ]]; then
    log_info "克隆仓库: $repo_url → $repo_dir"
    if ! exec_record "git clone --origin origin  \"$repo_url\"  \"$repo_dir\" "; then
      log_error "clone 失败"
      return 1
    fi
  fi


  # CHECK_LOCAL
  log_info "测试本地是否有版本"
  if repo_has_ver_local "$repo_dir" "$ver"; then
    log_info "checkout $ver"
    exec_record "git -C \"$repo_dir\" checkout \"$ver\"  " || {
      log_error "checkout 失败"
      return 1
    }
    return 0
  fi


  # FETCH
  log_info "fetch 更新仓库"
  if ! exec_record "git -C \"$repo_dir\" fetch --tags origin"; then
    log_error "fetch 失败"
    return 1
  fi


  if repo_has_ver_remote "$repo_dir" "${ver}"; then
    :
  else
    log_error "远端仓库不存在版本: $ver"
    print_repo_refs_remote "$repo_dir"
    #exec_record " git ls-remote ${repo_url}"
    return 3
  fi

  # CHECK_LOCAL AGAIN
  if repo_has_ver_local "$repo_dir" "$ver"; then
    log_info "checkout $ver"

    exec_record "git -C \"$repo_dir\" checkout \"$ver\" " || {
      log_error "checkout 失败"
      return 1
    }
    return 0
  fi

  return 0
}


#configure_git_repo(){
#  local dep="$1"
#  local ver="$2"
#  local opts="$3"
#  ensure_repo_version "${dep}" "${ver}"
#  local repo_dir="${_git_cache_dir_}/${dep}"
#  configure_gnu_ex "${repo_dir}" "$opts"
#}


