#!/bin/sh
set -euC

# usage: distro-url [query] [guess] [<distro> [<variant> [<arch> [<codename> [<version> [<mirror>]]]]]]

main()
{
  [ "${1:-}" = 'query' ] && shift && query='QUERY' || query=
  [ "${1:-}" = 'guess' ] && shift && guess='GUESS' || guess=
  {
    echo 'DISTRO' 'VARIANT' 'ARCH' 'CODENAME' 'VERSION' 'URL' $query
    [ "$guess" ] \
      && guess  "$@" \
      || filter "$@"
  } \
  | {
    [ "$(command -v column)" ] \
      && column -t \
      || cat
  } \
  | while IFS= read -r line
  do
    printf '%s' "$line"
    set -- $line
    [ "$query" ] && [ "$6" != 'URL' ] && query "$6"
    printf '\n'
  done
}

colorize()
{
  if [ "$(command -v tput)" ] && [ -t 1 ]
  then
    tput setaf "$1"
    printf '%s' "$2"
    tput sgr0
  else
    printf '%s' "$2"
  fi
}

query()
{
  curl -sfI "$1" > '/dev/null' \
    && colorize 10 'OK' \
    || colorize  9 'ERR'
}

filter()
{
  distro="${1:-*}"
  variant="${2:-*}"
  arch="${3:-*}"
  codename="${4:-}"
  version="${5:-}"
  try()
  {
    for d in $1; do case "$d" in $distro)
    for v in $2; do case "$v" in $variant)
    for a in $3; do case "$a" in $arch)
      guess "$d" "$v" "$a" "$codename" "$version"
    esac; done
    esac; done
    esac; done
  }
  try 'debian'         'netinst inst                                   ' 'amd64 arm64 armhf ppc64el riscv64 s390x'
  try 'debian'         'standard gnome kde lxqt xfce cinnamon mate lxde' 'amd64                                  '
  try 'debian'         'raspi                                          ' '      arm64                            '
  try 'raspios'        'default full lite                              ' '      arm64 armhf                      '
  try 'ubuntu'         'desktop       server                           ' 'amd64                                  '
  try 'ubuntu'         'desktop-raspi server-raspi                     ' '      arm64                            '
  try 'edubuntu'       'desktop                                        ' 'amd64                                  '
  try 'edubuntu'       'desktop-raspi                                  ' '      arm64                            '
  try 'kubuntu'        'desktop                                        ' 'amd64                                  '
  try 'lubuntu'        'desktop                                        ' 'amd64                                  '
  try 'xubuntu'        'desktop                                        ' 'amd64                                  '
  try 'ubuntucinnamon' 'desktop                                        ' 'amd64                                  '
  try 'ubuntu-mate'    'desktop                                        ' 'amd64                                  '
  try 'ubuntu-budgie'  'desktop                                        ' 'amd64                                  '
  try 'ubuntu-unity'   'desktop                                        ' 'amd64                                  '
  try 'ubuntustudio'   'desktop                                        ' 'amd64                                  '
  try 'ubuntukylin'    'desktop                                        ' 'amd64                                  '
  try 'linuxmint'      'cinnamon mate xfce                             ' 'amd64                                  '
  try 'opensuse'       'netinst inst                                   ' 'amd64                                  '
  try 'opensuse'       'gnome kde xfce                                 ' 'amd64                                  '
}

guess()
(
  distro="${1:-}"
  variant="${2:-}"
  arch="${3:-}"
  codename="${4:-}"
  version="${5:-}"
  vars()  { printf '%s ' "$distro" "$variant" "$arch" "$codename" "$version"; }
  lower() { printf '%s\n' "$1" | tr 'A-Z' 'a-z'; }
  upper() { printf '%s\n' "$1" | tr 'a-z' 'A-Z'; }
  case "$distro/$variant" in
    *raspi*) : ${arch:="arm64"}; ext='img.xz'; ;;
    *)       : ${arch:="amd64"}; ext='iso';    ;;
  esac
  case "$distro" in
    debian)
      : ${variant:="gnome"}
      : ${codename:="trixie"}
      : ${version:="13.5.0"}
      vars
      case "$variant" in
        raspi)
          # : ${mirror:="https://get.debian.org/images/cloud"}
          # : ${mirror:="https://cdimage.debian.org/images/cloud"}
          : ${mirror:="https://cloud.debian.org/images/cloud"}
          major="${version%%.*}"
          ext='tar.xz'
          # dir="$codename/latest"
          # echo "$mirror/$dir/$distro-$major-$variant-$arch.$ext"
          dir="$codename/daily/latest"
          echo "$mirror/$dir/$distro-$major-$variant-$arch-daily.$ext"
          ;;
        *)
          # : ${mirror:="https://get.debian.org/images/release"}
          # : ${mirror:="https://cdimage.debian.org/images/release"}
          # : ${mirror:="https://cloud.debian.org/images/release"}
          : ${mirror:="https://cdimage.debian.org/debian-cd"}
          case "$variant" in
            netinst) media='iso-cd';     suffix='';                       ;;
            inst)    media='iso-dvd';    suffix='';      variant='DVD-1'; ;;
            *)       media='iso-hybrid'; suffix='-live';                  ;;
          esac
          dir="$version$suffix/$arch/$media"
          echo "$mirror/$dir/$distro$suffix-$version-$arch-$variant.$ext"
          ;;
      esac
      ;;
    raspios)
      : ${variant:="default"}
      : ${codename:="trixie"}
      : ${version:="2026-04-21"}
      : ${mirror:="https://downloads.raspberrypi.com"}
      vars
      case "$variant" in
        default) name="${distro}_${arch}";            suffix='';          ;;
        *)       name="${distro}_${variant}_${arch}"; suffix="-$variant"; ;;
      esac
      dir="$name/images/$name-$version"
      echo "$mirror/$dir/$version-$distro-$codename-$arch$suffix.$ext"
      ;;
    ubuntu|\
    edubuntu|\
    kubuntu|lubuntu|xubuntu|\
    ubuntucinnamon|ubuntu-mate|ubuntu-budgie|ubuntu-unity|\
    ubuntustudio|ubuntukylin)
      : ${variant:="desktop"}
      : ${codename:="resolute"}
      : ${version:="26.04"}
      vars
      if [ "$distro/$arch" = 'ubuntu/amd64' ]
      then : ${mirror:="https://releases.ubuntu.com"};                 dir="$codename";
      else : ${mirror:="https://cdimage.ubuntu.com/$distro/releases"}; dir="$codename/release";
      fi
      case "$variant" in
        server)  suffix='-live'; ;;
        *-raspi) suffix='-preinstalled'; variant="${variant%%-raspi}"; arch="$arch+raspi"; ;;
        *) suffix=''; ;;
      esac
      echo "$mirror/$dir/$distro-$version$suffix-$variant-$arch.$ext"
      ;;
    linuxmint)
      : ${variant:="cinnamon"}
      : ${codename:="zena"}
      : ${version:="22.3"}
      : ${mirror:="https://pub.linuxmint.io"}
      vars
      case "$arch" in
        amd64) arch='64bit' ;;
      esac
      dir="stable/$version"
      echo "$mirror/$dir/$distro-$version-$variant-$arch.$ext"
      ;;
    opensuse)
      : ${variant:="gnome"}
      : ${codename:="tumbleweed"}
      : ${version:="-"}
      : ${mirror:="https://download.opensuse.org"}
      vars
      distro='openSUSE'
      case "$codename" in
        tumbleweed) codename='Tumbleweed' ;;
      esac
      case "$variant" in
        inst)    suffix='';      variant='DVD';                 ;;
        netinst) suffix='';      variant='NET';                 ;;
        *)       suffix='-Live'; variant="$(upper "$variant")"; ;;
      esac
      case "$arch" in
        amd64) arch='x86_64'
      esac
      dir="$codename/iso"; dir="$(lower "$dir")";
      echo "$mirror/$dir/$distro-$codename-$variant$suffix-$arch-Current.$ext"
      ;;
  esac
)

main "$@"
