#!/bin/bash
# shellcheck disable=SC2155
# 已经过时  winrar本身就支持软链接的复制




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
#        C:\Users\wyc>mklink /?
#        创建符号链接。
#
#        MKLINK [[/D] | [/H] | [/J]] Link Target
#
#        /D      创建目录符号链接。默认为文件符号链接。
#        /H      创建硬链接而非符号链接。  (硬链接本质上是：一个文件内容，对应多个文件名, 所以硬链接没有“谁是原件、谁是副本”这个区别)
#        /J      创建目录联接。
#        Link    指定新的符号链接名称。
#        Target  指定新链接引用的路径
#        (相对或绝对)。
# dir /al
#     wyc@ubuntu:/$ ln --help
#     用法：ln [选项]... [-T] 目标 链接名
#     　或：ln [选项]... 目标
#     　或：ln [选项]... 目标... 目录
#     　或：ln [选项]... -t 目录 目标...
#     在第一种格式中，创建具有指定<链接名>且指向指定<目标>的链接。
#     在第二种格式中，在当前目录创建指向<目标>位置的链接。
#     在第三、四种格式中，在指定<目录>中创建指向指定<目标>的链接。
#     默认创建硬链接，当使用--symbolic 时创建符号链接。
#     默认情况下，创建每个目标时不应存在与新链接的名称相同的文件。
#     创建硬链接时，每个指定的<目标>都必须存在。符号链接可以指向任意的位置；
#     当链接解析正常时，将其解析为一个相对于其父目录的相对链接。
#
#     必选参数对长短选项同时适用。
#     --backup[=CONTROL]      为每个已存在的目标文件创建备份文件
#     -b                          类似--backup，但不接受任何参数
#     -d, -F, --directory         允许超级用户尝试创建指向目录的硬链接
#     （注意：此操作可能因系统限制而失败)
#     --logical               如目标为符号链接，本次创建链接时将其解引用
#     -n, --no-dereference        如果给定<链接名>是一个链接至某目录的符号链接，
#     将其作为普通文件处理
#     -P, --physical              创建直接指向符号链接文件的硬链接
#     -r, --relative              创建相对于链接位置的符号链接
#     -s, --symbolic              创建符号链接而非硬链接
#     -S, --suffix=后缀           自行指定备份文件的后缀
#     -t, --target-directory=目录  在指定<目录>中创建链接
#     -T, --no-target-directory   总是将给定的<链接名>当作普通文件
#     -v, --verbose               列出每个链接的文件名称
#     --help            显示此帮助信息并退出
#     --version         显示版本信息并退出
#
#     备份文件的后缀为"~"，除非以--suffix 选项或是 SIMPLE_BACKUP_SUFFIX
#     环境变量指定。版本控制的方式可通过--backup 选项或 VERSION_CONTROL 环境
#     变量来选择。以下是可用的变量值：
#
#     none, off       不进行备份(即使使用了--backup 选项)
#     never   永远使用普通方式备份
#
#     使用 -s 选项会忽略 -L 和 -P。
#     否则当<目标>为一个符号链接（默认为 -P）时，会由最后一个指定的选项来控制行为。
#
#     GNU coreutils 在线帮助：<https://www.gnu.org/software/coreutils/>
#     请向 <http://translationproject.org/team/zh_CN.html> 报告 ln 的翻译错误
#     完整文档请见：<https://www.gnu.org/software/coreutils/ln>
#     或者在本地使用：info '(coreutils) ln invocation'


# TODO: 支持复杂的参数  还是通过全局变量来实现
# TODO: 远程get_sysroot  qt 构建重构

export glmf_include_dir_list
export glmf_exclude_dir_list


generate_link_meta_file() {
  local source_dir="$1"
  local dir_name parent_dir
  dir_name="$(basename "$source_dir")"
  parent_dir="$(dirname "$source_dir")"
  local target_dir="${3:-${parent_dir}/${dir_name}_origin}"
  local meta_file="${4:-${target_dir}_meta.txt}"


  # cp不会保留硬链接关系，硬链接被当成真实文件拷贝，软链接仍然存在
  cp -r --no-preserve=mode "${source_dir}" "${target_dir}"
  local rlink_type # file dir broken
  local target_link # 软链接目标（可能仍然是软链接）
  local under_source_dir # 0 在 source_dir 下 1 不在
  local abs_rlink # 0 绝对路径 1 相对路径
  local resolved # 链接到最后的真实文件或目录路径
  local dir # 原始软链接所在的目录
  local rel # 软链接相对于 source_dir的目录
  while IFS= read -r -d '' link; do
    # 读取软链接目标
    rel=${link#"$source_dir"/}
    rm "$target_dir/$rel"
    target_link="$(readlink "$link")"
    dir=${link%/*}
    # 判断是否绝对路径
    if [[ "$target_link" == /* ]]; then
      abs_rlink=0
      resolved="$target_link"
    else
      abs_rlink=1
      resolved="$dir/$target_link"
    fi
    resolved=$(realpath -m "$resolved")
    # 判断是否存在
    if [[ ! -e "$resolved" ]]; then
      rlink_type="broken"
    elif [[ -d "$resolved" ]]; then
      rlink_type="dir"
    elif [[ -f "$resolved" ]]; then
      rlink_type="file"
    else
      rlink_type="broken"
    fi
    # 判断是否是source_dir  或者在source_dir下
    case "$resolved" in "$source_dir" | "$source_dir"/*)
      under_source_dir=0
      ;;
    *)
      under_source_dir=1
      ;;
    esac


    printf "%s|%s|%s|%s|%s" \
      "$rel" "$target_link" "$rlink_type" "$under_source_dir" "$abs_rlink"
  done < <(find "$source_dir" -type l -print0)
}
