#! /usr/bin/env bash

# Download and arrange source and binary packages.
#
# Run from the root of the destination download directory. Note that the
# destination files are expected not to exist.

repo="https://queue.stage.build2.org"

bin_repo="$repo/0/bindist"
src_repo="$repo/1/alpha"

declare -A vers
declare -A srcs
declare -A bins

# Key is project name.
#
vers["xsd"]="4.2.0"
vers["xerces-c"]="3.2.4+2"
vers["libcutl"]="1.11.0"
vers["libxsd-frontend"]="2.1.0"

# Key is package name, value is project name (for version).
#
srcs["xsd"]="xsd"
srcs["xsd-tests"]="xsd"
srcs["xsd-examples"]="xsd"
srcs["libxsd"]="xsd"
srcs["libxsd-tests"]="xsd"
srcs["libcutl"]="libcutl"
srcs["libxsd-frontend"]="libxsd-frontend"
srcs["libxerces-c"]="xerces-c"

# The key is "<dist>/<os>/<proj>/<pkg>/<cfg>". The value is the destination
# subdirectory.
#
# @@ TODO: replace default <cfg> with arch, etc.
#
bins["debian/debian11/xsd/xsd/default"]="debian/debian11/x86_64"
bins["debian/debian11/xsd/libxsd/default"]="debian/debian11/x86_64"

bins["debian/debian12/xsd/xsd/default"]="debian/debian12/x86_64"
bins["debian/debian12/xsd/libxsd/default"]="debian/debian12/x86_64"

bins["debian/ubuntu22.04/xsd/xsd/default"]="ubuntu/ubuntu22.04/x86_64"
bins["debian/ubuntu22.04/xsd/libxsd/default"]="ubuntu/ubuntu22.04/x86_64"
bins["debian/ubuntu22.04/xerces-c/libxerces-c/default"]="ubuntu/ubuntu22.04/x86_64"

bins["fedora/fedora37/xsd/xsd/default"]="fedora/fedora37/x86_64"
bins["fedora/fedora37/xsd/libxsd/default"]="fedora/fedora37/x86_64"

bins["fedora/fedora38/xsd/xsd/default"]="fedora/fedora38/x86_64"
bins["fedora/fedora38/xsd/libxsd/default"]="fedora/fedora38/x86_64"

bins["fedora/rhel9.2/xsd/xsd/default"]="rhel/rhel9.2/x86_64"
bins["fedora/rhel9.2/xsd/libxsd/default"]="rhel/rhel9.2/x86_64"
bins["fedora/rhel9.2/xerces-c/libxerces-c/default"]="rhel/rhel9.2/x86_64"

bins["archive/debian11/xsd/xsd/linux-glibc2_31"]="linux/linux-glibc2.31/x86_64"
bins["archive/debian11/xsd/libxsd/linux"]="linux/linux-glibc2.31/x86_64"

bins["archive/macos13.4/xsd/xsd/default"]="macos/macos13.4/x86_64"
bins["archive/macos13.4/xsd/libxsd/default"]="macos/macos13.4/x86_64"
bins["archive/macos13.4/xerces-c/libxerces-c/default"]="macos/macos13.4/x86_64"

bins["archive/windows10/xsd/xsd/default"]="windows/windows10/x86_64"
bins["archive/windows10/xsd/libxsd/default"]="windows/windows10/x86_64"
bins["archive/windows10/xerces-c/libxerces-c/release"]="windows/windows10/x86_64"
bins["archive/windows10/xerces-c/libxerces-c/debug"]="windows/windows10/x86_64"

owd=`pwd`
trap "{ cd $owd; exit 1; }" ERR
set -o errtrace # Trap in functions.
shopt -s lastpipe # Execute last pipeline command in current shell.

function info () { echo "$*" 1>&2; }
function error () { info "$*"; exit 1; }

declare -A dirs # Package directories to generate packages.sha256 in.

# Download and arrange sources.
#
if true; then
for pkg in "${!srcs[@]}"; do
  prj="${srcs[$pkg]}"
  ver="${vers[$prj]}"

  pkgf="$pkg-$ver.tar.gz"
  url="$src_repo/$prj/$pkgf"

  info "fetching $url"
  curl -sSf -o "$pkgf" "$url"

  # Make .zip archive for examples.
  #
  if [ -n "$(sed -rn -e 's/^.+-examples$/true/p' <<<"$pkg")" ]; then
    pkgd="$pkg-$ver"

    if [ -d "$pkgd" ]; then
      error "package directory $pkgd already exist"
    fi

    info "repacking $pkgf"
    tar -xf "$pkgf"
    zip -r "$pkg-$ver.zip" "$pkgd"
    rm -rf "$pkgd"
  fi
done
dirs["."]=true
fi

# Download and arrange binaries.
#
if true; then
for bk in "${!bins[@]}"; do
  bv="${bins[$bk]}"

  # Get the distribution type we are dealing with.
  #
  dist="$(sed -rn -e 's#^(.+)/.+/.+/.+/.+$#\1#p' <<<"$bk")"

  # Get the project we are dealing with and its version.
  #
  prj="$(sed -rn -e 's#^.+/.+/(.+)/.+/.+$#\1#p' <<<"$bk")"
  ver="${vers[$prj]}"

  url="$bin_repo/"
  url+="$(sed -rn -e "s#^(.+/.+/.+/.+)/(.+)\$#\\1/$ver/\\2#p" <<<"$bk")"

  # Get the list of packages (keys) and their checksums (values) at this URL
  # by loading its packages.sha256.
  #
  unset pkgs # Clear.
  declare -A pkgs

  curl -sSf "$url/packages.sha256" | while read l; do

    pkg="$(sed -rn -e 's#^([^ ]+) \*(.+)$#\2#p' <<<"$l")"

    # Get the extension and omit certain distribution-specific file types.
    #
    e="$(sed -rn -e 's#^.+\.([^.]+)$#\1#p' <<<"$pkg")"

    case "$dist" in
      "debian")
	if [ "$e" = "buildinfo" -o "$e" = "changes" ]; then
	  continue
	fi
	;;

      "fedora")
	;;
    esac

    csm="$(sed -rn -e 's#^([^ ]+) \*(.+)$#\1#p' <<<"$l")"
    pkgs["$pkg"]="$csm"
  done

  mkdir -p "$bv"

  # Download each package and verify checksum.
  #
  for pkg in "${!pkgs[@]}"; do

    pkgf="$bv/$pkg"

    if [ -f "$pkgf" ]; then
      error "destination package $pkgf from $bk already exist"
    fi

    info "fetching $url/$pkg"
    curl -sSf -o "$pkgf" "$url/$pkg"

    csm="$(sha256sum -b "$pkgf" | sed -rn -e 's#^([^ ]+) \*(.+)$#\1#p')"

    if [ "$csm" != "${pkgs[$pkg]}" ]; then
      error "checksum mismatch for package $pkgf from $bk"
    fi

  done

  dirs["$bv"]=true
done
fi

# Generate packages.sha256
#
for d in "${!dirs[@]}"; do
  cd "$d"
  rm -f "packages.sha256"
  l="$(find . -maxdepth 1 -type f -printf '%P\n' | sort)" # Array-like.
  sha256sum -b $l >"packages.sha256"
  cd "$owd"
done