#! /usr/bin/env bash

# Stage or queue build2 packages and distributions.
#
# -b
#    Packages baseutils/mingw.
# -o
#    Only package baseutils/mingw.
# -s
#    Only prepare the install scripts and regenerate toolchain.sha256.
# -q
#    Put packages into the queue instead of staging. Used to update for
#    queue.
# -p
#    Regenerate build2-toolchain into queue's 0/ and update the checksums file
#    but don't do anything else. Used to update for public.
#
usage="usage: etc/stage"

rsync_ops="--progress"

owd=`pwd`
trap "{ cd $owd; exit 1; }" ERR
set -o errtrace # Trap in functions.

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

v="$(sed -n -re 's/^version: ([^.]+\.[^.]+\.[^-]+(-[ab]\.[^.+]+)?).*$/\1/p' build2-toolchain/manifest)"
vf="$(echo $v | sed -re 's/^([^.]*)\.([^.]*)\.([^-]*).*$/\1.\2.\3/')" # Final.

if [ -z "$v" -o -z "$vf" ]; then
  error "unable to extract version from build2-toolchain/version"
fi

mode=
base=
base_only=
script_only=

dist_src=staging/0
dist_dst=stage.build2.org:/var/www/stage.build2.org/public/0

while [ $# -gt 0 ]; do
  case $1 in
    -b)
      base=true
      shift
      ;;
    -o)
      base_only=true
      shift
      ;;
    -s)
      script_only=true
      shift
      ;;
    -q)
      mode=-q
      dist_src=cppget.org/0
      dist_dst=build2.org:/var/www/download.build2.org/public/queue
      shift
      ;;
    -p)
      mode=-p
      dist_src=cppget.org/0
      dist_dst=example.org/not-used
      shift
      ;;
    *)
      error "unexpected $1"
      ;;
  esac
done

# Note that this structure is seriously hard-wired in the install scripts.
# Specifically, they assume paths in toolchain.sha256 are in the <ver>/<file>
# form.
#
mkdir -p "$dist_src/$v"

# Generate baseutils if requested.
#
if [ "$base" = true ]; then
  cd private/baseutils

  echo "$v" >version

  ./pkdist -n baseutils -d "$vf" -z "/tmp/build2-baseutils-$v-i686-windows" \
--sys-p "$vf/list-msys-i686" \
--sys-c "$vf/control-msys" \
--sys-s ./pkpost-base-msys \
--min-p "$vf/list-mingw-i686" \
--min-c "$vf/control-mingw-i686" \
--min-s ./pkpost-base-mingw

  ./pkdist -n baseutils -d "$vf" -z "/tmp/build2-baseutils-$v-x86_64-windows" \
--sys-p "$vf/list-msys-x86_64" \
--sys-c "$vf/control-msys" \
--sys-s ./pkpost-base-msys \
--min-p "$vf/list-mingw-x86_64" \
--min-c "$vf/control-mingw-x86_64" \
--min-s ./pkpost-base-mingw

  ./pkdist -n mingw -d "mingw-$vf" -x "/tmp/build2-mingw-$v-i686-windows" \
--min-p "mingw-$vf/list-mingw-i686" \
--min-c "mingw-$vf/control-mingw-i686" \
--min-s ./pkpost-mingw-mingw

  ./pkdist -n mingw -d "mingw-$vf" -x "/tmp/build2-mingw-$v-x86_64-windows" \
--min-p "mingw-$vf/list-mingw-x86_64" \
--min-c "mingw-$vf/control-mingw-x86_64" \
--min-s ./pkpost-mingw-mingw

  cd ../..

  mv "/tmp/build2-baseutils-$v-i686-windows.zip" "$dist_src/$v/"
  mv "/tmp/build2-baseutils-$v-i686-windows.zip.sha256" "$dist_src/$v/"

  mv "/tmp/build2-baseutils-$v-x86_64-windows.zip" "$dist_src/$v/"
  mv "/tmp/build2-baseutils-$v-x86_64-windows.zip.sha256" "$dist_src/$v/"

  mv "/tmp/build2-mingw-$v-i686-windows.tar.xz" "$dist_src/$v/"
  mv "/tmp/build2-mingw-$v-i686-windows.tar.xz.sha256" "$dist_src/$v/"

  mv "/tmp/build2-mingw-$v-x86_64-windows.tar.xz" "$dist_src/$v/"
  mv "/tmp/build2-mingw-$v-x86_64-windows.tar.xz.sha256" "$dist_src/$v/"
fi

if [ "$base_only" = true ]; then
  exit 0
fi

##
##if false; then

mkdir -p /tmp/dist

# Dist build2-toolchain.
#
if [ "$script_only" != true ]; then

  # Cleanup old stuff.
  #
  rm -f "$owd/$dist_src/$v"/build2-toolchain-*

  b "dist(build2-toolchain-default/)" \
    "config.dist.archives=$owd/$dist_src/$v/tar.xz $owd/$dist_src/$v/tar.gz"

  cd "$owd/$dist_src/$v/"

  tv="$(echo build2-toolchain-*.tar.gz | sed -re 's/build2-toolchain-(.+).tar.gz/\1/')"

  sha256sum -b "build2-toolchain-$tv.tar.gz" >"build2-toolchain-$tv.tar.gz.sha256"
  sha256sum -b "build2-toolchain-$tv.tar.xz" >"build2-toolchain-$tv.tar.xz.sha256"

  cd "$owd"
else
  cd "$owd/$dist_src/$v/"
  tv="$(echo build2-toolchain-*.tar.gz | sed -re 's/build2-toolchain-(.+).tar.gz/\1/')"
  cd "$owd"
fi

# Prepare the toolchain.sha256 checksums file.
#
function checksum_line () # <file>
{
  local s
  s="$(sed -n -re 's/^([^ ]+) .+$/\1/p' "$dist_src/$v/$1.sha256")"
  echo "$s *$v/$1" >>"$dist_src/toolchain.sha256"
}

echo "# $tv" >"$dist_src/toolchain.sha256"
checksum_line "build2-toolchain-$tv.tar.xz"              # Must be first.
checksum_line "build2-baseutils-$v-x86_64-windows.zip"
checksum_line "build2-mingw-$v-x86_64-windows.tar.xz"
#checksum_line "build2-baseutils-$v-i686-windows.zip"
#checksum_line "build2-mingw-$v-i686-windows.tar.xz"

# Prepare install script/batch files and then append their checksums to
# toolchain.sha256.
#
case "$mode" in
  -q) o=--queue ;;
  -p) o=        ;;
   *) o=--stage ;;
esac

scripts=($(private/install/prepare $o "$dist_src"))

for f in "${scripts[@]}"; do
  info "prepared $f"
  checksum_line "$f"
done

if [ "$mode" = "-p" ]; then
  exit 0
fi

# Sync the distribution.
#
# Note that we do the distribution first so that the toolchain changes are
# visible before package changes. This is relied upon by the Build OS monitor.
#
info "Press Enter to start distribution upload"
read
rsync -v -rlpt -c --copy-unsafe-links --prune-empty-dirs --delete-after \
  $rsync_ops "$dist_src/" "$dist_dst/"

##fi
##

if [ "$script_only" = true ]; then
  exit 0
fi

# Distribute packages, regenerate and sync the repository.
#

# These are just for testing (though libodb-mysql needs libmysqlclient).
#
etc/stage-pkg -c $mode -d vcpkg packaging/vcpkg/vcpkg

etc/stage-pkg -c $mode -d mariadb packaging/mariadb/libmariadb
etc/stage-pkg -c $mode -d mysql packaging/mysql/libmysqlclient

etc/stage-pkg -c $mode -d cutl ../cutl/libcutl
etc/stage-pkg -c $mode -d cli ../cli/cli

#
#
etc/stage-pkg -c $mode -d apr packaging/apr/libapr1
etc/stage-pkg -c $mode -d postgresql packaging/postgresql/libpq

etc/stage-pkg -c $mode -d sqlite \
	      packaging/sqlite/libsqlite3 \
	      packaging/sqlite/sqlite3

etc/stage-pkg -c $mode -d pkgconf packaging/pkgconf/libpkgconf

etc/stage-pkg -c $mode -d studxml ../studxml/libstudxml

etc/stage-pkg -c $mode -d hello hello/libhello-1.0

# For now we also stage libodb-mysql.
#
etc/stage-pkg -c $mode -d odb \
	      ../odb/odb \
	      ../odb/builds/default/libodb \
	      ../odb/builds/default/libodb-sqlite \
	      ../odb/builds/default/libodb-pgsql \
	      ../odb/builds/default/libodb-mysql \
	      ../odb/builds/default/libodb-oracle \
	      ../odb/builds/default/libodb-mssql

etc/stage-pkg -c $mode build2 \
	      libbutl \
	      build2 \
	      libbpkg \
	      bpkg \
	      bdep \
	      libbbot \
	      brep \
	      bbot \
              libstd-modules