#!/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 export.bash



parse_triplet() {
    local TRIPLET=$1
    local -n CPU_VAR=$2
    local -n VENDOR_VAR=$3
    local -n OS_VAR=$4
    local -n ABI_VAR=$5

    # Extract and assign parts from $TRIPLET
    CPU_VAR=${TRIPLET%%-*}                         # Extract 'cpu'
    local TRIPLET_REMAINDER=${TRIPLET#*-}          # Remaining parts after 'cpu'
    if [[ "$TRIPLET_REMAINDER" == "$TRIPLET" ]]; then
        return 1
    fi

    # Extract TRIPLET_VENDOR and update TRIPLET_REMAINDER
    if [[ "$TRIPLET_REMAINDER" == *-* ]]; then
        VENDOR_VAR=${TRIPLET_REMAINDER%%-*}        # Extract 'vendor'
        TRIPLET_REMAINDER=${TRIPLET_REMAINDER#*-}  # Update TRIPLET_REMAINDER
    else
        VENDOR_VAR=""
    fi

    # Correct behavior if TRIPLET_VENDOR is 'linux'
    if [[ "$VENDOR_VAR" == "windows" ]]; then
        VENDOR_VAR=""                              # Clear TRIPLET_VENDOR as 'windows' is part of TRIPLET_OS
        OS_VAR="windows"                           # Shift TRIPLET_OS from TRIPLET_REMAINDER
        ABI_VAR=${TRIPLET_REMAINDER#*-}            # Extract 'abi' from TRIPLET_REMAINDER
    elif [[ "$VENDOR_VAR" == "linux" ]]; then
        VENDOR_VAR=""                              # Clear TRIPLET_VENDOR as 'linux' is part of TRIPLET_OS
        OS_VAR="linux"                             # Shift TRIPLET_OS from TRIPLET_REMAINDER
        ABI_VAR=${TRIPLET_REMAINDER#*-}            # Extract 'abi' from TRIPLET_REMAINDER
    else
        # Normal behavior for non-'linux' TRIPLET_VENDOR
        if [[ "$TRIPLET_REMAINDER" == *-* ]]; then
            OS_VAR=${TRIPLET_REMAINDER%%-*}        # Extract 'os'
            ABI_VAR=${TRIPLET_REMAINDER#*-}        # Extract 'abi'
        else
            OS_VAR=$TRIPLET_REMAINDER              # Remaining part becomes OS
            ABI_VAR=""
        fi
    fi

    return 0
}

detect_platform_triplet() {
    local -n triplet=$1         # Name reference to the first argument
    local -n triplet_no_vendor=$2  # Name reference to the second argument

    # Get the target platform from gcc if available
    if command -v gcc &> /dev/null; then
        triplet=$(gcc -dumpmachine)
    elif command -v clang &> /dev/null; then
        # Get the target platform from clang if gcc is not available
        triplet=$(clang -dumpmachine)
    else
        triplet="unknown-unknown-unknown-unknown"
    fi

    # Parse triplet and compute triplet_no_vendor
    local cpu
    local vendor
    local os
    local abi
    parse_triplet "$triplet" cpu vendor os abi   # Ensure parse_triplet is defined and works properly

    triplet_no_vendor="$cpu-$os-$abi"  # Assign the processed value to the referenced variable
}

compose_triplet(){
  local -n OUT_VAR=$1
  local cpu="$2"
  local vendor="$3"
  local os="$4"
  local abi="$5"
  local out=""
  for part in "$cpu" "$vendor" "$os" "$abi";do
    if [[ -n "$part" ]];then
      if [[ -n "$out" ]];then
        out="${out}-${part}"
      else
        out="$part"
      fi
    fi
  done
  OUT_VAR="$out"
}

#local new_triplet
#compose_triplet new_triplet "$cpu" "$vendor" "$os" "$abi"
#echo "$new_triplet"



#parse_triplet "x86_64-w64-mingw32" cpu vendor os abi
#cmake_os=""
#cmake_cpu=""
#gnu_os_to_cmake_system_name "$os" cmake_os
#gnu_cpu_to_cmake_system_processor "$cpu" cmake_cpu
#echo "OS  -> $cmake_os"
#echo "CPU -> $cmake_cpu"
gnu_os_to_cmake_system_name() {
  if [ $# -ne 2 ]; then
    echo "gnu_os_to_cmake_system_name: usage: <IN_OS> <OUT_VAR>" >&2
    return 1
  fi

  local in_os="$1"
  local -n out_var="$2"

  if [ -z "$in_os" ]; then
    echo "gnu_os_to_cmake_system_name: empty OS" >&2
    return 1
  fi

  # 转小写
  local os
  os="$(echo "$in_os" | tr 'A-Z' 'a-z')"

  if [[ "$os" =~ ^linux ]]; then
    out_var="Linux"

  elif [[ "$os" =~ mingw || "$os" =~ windows || "$os" =~ win32 ]]; then
    out_var="Windows"

  elif [[ "$os" =~ cygwin ]]; then
    out_var="Windows"

  elif [[ "$os" =~ darwin || "$os" =~ macos || "$os" =~ macosx ]]; then
    out_var="Darwin"

  elif [[ "$os" =~ ios ]]; then
    out_var="iOS"

  elif [[ "$os" =~ android ]]; then
    out_var="Android"

  elif [[ "$os" =~ freebsd ]]; then
    out_var="FreeBSD"

  elif [[ "$os" =~ openbsd ]]; then
    out_var="OpenBSD"

  elif [[ "$os" =~ netbsd ]]; then
    out_var="NetBSD"

  elif [[ "$os" =~ solaris ]]; then
    out_var="SunOS"

  elif [[ "$os" =~ aix ]]; then
    out_var="AIX"

  elif [[ "$os" =~ none || "$os" =~ elf ]]; then
    out_var="Generic"

  else
    echo "gnu_os_to_cmake_system_name: Unknown GNU OS: $in_os" >&2
    return 1
  fi
}

gnu_cpu_to_cmake_system_processor() {
  if [ $# -ne 2 ]; then
    echo "gnu_cpu_to_cmake_system_processor: usage: <IN_CPU> <OUT_VAR>" >&2
    return 1
  fi

  local in_cpu="$1"
  local -n out_var="$2"

  # 转小写
  local cpu
  cpu="$(echo "$in_cpu" | tr 'A-Z' 'a-z')"

  if [[ "$cpu" == "x86_64" || "$cpu" == "amd64" ]]; then
    out_var="x86_64"

  elif [[ "$cpu" =~ ^i[3-6]86$ ]]; then
    out_var="x86"

  elif [[ "$cpu" == "aarch64" || "$cpu" == "arm64" ]]; then
    out_var="aarch64"

  elif [[ "$cpu" =~ ^arm ]]; then
    out_var="arm"

  elif [[ "$cpu" =~ ^riscv64 ]]; then
    out_var="riscv64"

  elif [[ "$cpu" =~ ^riscv32 ]]; then
    out_var="riscv32"

  elif [[ "$cpu" =~ ^ppc64le ]]; then
    out_var="ppc64le"

  elif [[ "$cpu" =~ ^ppc64 ]]; then
    out_var="ppc64"

  elif [[ "$cpu" =~ ^ppc ]]; then
    out_var="ppc"

  else
    # fallback：原样
    out_var="$cpu"
  fi
}

gnu_triple_to_suffixes() {
  if [ $# -ne 5 ]; then
    echo "usage: <triple> <exe_var> <shared_var> <static_var> <lib_prefix_var>" >&2
    return 1
  fi

  local triple="$1"
  local -n exe_var="$2"
  local -n shared_var="$3"
  local -n static_var="$4"
  local -n lib_prefix_var="$5"

  # 默认（Linux/Unix）
  exe_var=""
  shared_var=".so"
  static_var=".a"
  lib_prefix_var="lib"

  if [[ "$triple" =~ mingw || "$triple" =~ windows || "$triple" =~ win32 ]]; then
    exe_var=".exe"
    shared_var=".dll"
    static_var=".lib"
    lib_prefix_var=""

  elif [[ "$triple" =~ darwin || "$triple" =~ apple ]]; then
    exe_var=""
    shared_var=".dylib"
    static_var=".a"
    lib_prefix_var="lib"

  elif [[ "$triple" =~ linux ]]; then
    exe_var=""
    shared_var=".so"
    static_var=".a"
    lib_prefix_var="lib"

  elif [[ "$triple" =~ android ]]; then
    exe_var=""
    shared_var=".so"
    static_var=".a"
    lib_prefix_var="lib"

  elif [[ "$triple" =~ freebsd ]]; then
    exe_var=""
    shared_var=".so"
    static_var=".a"
    lib_prefix_var="lib"

  elif [[ "$triple" =~ none || "$triple" =~ elf ]]; then
    exe_var=""
    shared_var=".elf"
    static_var=".a"
    lib_prefix_var="lib"

  else
    echo "unknown triple: $triple" >&2
    return 1
  fi
}


return 0