#!/bin/sh
## 
## Copyright 2015-2022, 2026 The Regents of the University of California
## All rights reserved.
## 
## This file is part of Spoofer.
## 
## Spoofer is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
## 
## Spoofer is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with Spoofer.  If not, see <http://www.gnu.org/licenses/>.
## 

# git repo for web: git@gitlab.caida.org:CAIDA/WEB/www-caida-web.git
websuffix=""
webdir="$HOME/lightweight-caida-web"
webstatic='static/projects/spoofer'
webcontent='content/projects/spoofer'
homebox="river"

stagedir=spoofer-stage

CONFIG_OPTIONS='--enable-manager'
revision=""
cs_dir="."
signed="signed"
signprefix=""
tarball=""
copyright="$(date +%Y)"

# prevent `cd` from using CDPATH (and printing the directory when it does)
unset CDPATH

usage() {
    cat >&2 <<EOF
usage: $0 {-u|-s<dir>} [-r<vcsrev>] [<options>] <version> <dist_type>... [web]

Exports revision <vcsrev> of spoofer from a git working directory into staging
directory "${stagedir}" and builds zero or more distributions.
If the staging directory already exists from a previous run of this script,
you are given the option to reuse it, which will also preserve
any distributions already built that weren't requested in this run.

After the distributions are built, you will be given instructions on next
steps (including for any distributions remaining from a previous run).

Options:
-u            binary distributions will be unsigned (default: signed)
-s <dir>      Windows binary distributions will be signed using files in <dir>
              (default: "$cs_dir")
-r <vcsrev>   check out revision "<vcsrev>"
              (default: "release-<version>", with each "." changed to "-")
-o <options>  additional options to pass to configure
-F            force version:  command line <version> overrides configure.ac
-t <tarball>  name of tarball file for "ubuntu" releases (defaults to tarball
              built by "src" argument)
-w <webdir>   name of working copy of caida website repo
              (default: "$webdir")
-W <websfx>   suffix for web git branch (useful for a repeat release)
              (default: "$websuffix")
-c <year>     copyright year for sanity check (useful for releasing an old
              version to a new platform) (default: $copyright)
-x            reprint accumulated "next steps" from previous runs, and exit

<dist_type> is one or more of the following:
  src           source distribution
  ubuntu[-<N>]  Ubuntu PPA version N, for all current Ubuntu series.  If N is
                omitted, it defaults to 1, and the debian log message will be
                "New upstream release."; otherwise you will be prompted for a
                log message.  To limit release to specific ubuntu series, set an
                environment variable e.g. SPOOFER_UBUNTU_SERIES="focal jammy".
                Normally requires "src" to be built first, but can also be
                built from a tarball indicated by "-t<tarball>" option.
  win32         Windows binary distribution (requires an MXE
                i686-w64-mingw32.static cross-compiling environment)
  mac           macOS binary distribution (requires macOS)
  web           (not actually a distribution) update a working copy of the
                CAIDA web site with information about all distributions in
                ${stagedir}.

Typical use:
  First, tag the version to be released:
    git tag release-X-Y-Z
    git push --tags
  Then, in a working dir on an ubuntu box with MXE:
    ./release -s ~/code-signing X.Y.Z src ubuntu win32
  Next (or in parallel), in a working dir on a mac box:
    ./release X.Y.Z mac
    ./release X.Y.Z web  ;# and follow its instructions
  Finally, in working dir on ubuntu box:
    ./release X.Y.Z web
EOF
}

assert() {
    local cmd="$*"
    echo "#  $cmd" >&2
    if test "$1" = "!"; then
	shift
	! "$@"
    else
	"$@"
    fi || { echo; echo "$0: assertion failed: $cmd"; exit 1; } >&2
}

finish() {
    local dist_class="$1"
    local prefix="$2"
    local version="$3"
    local suffix="$4"
    local desc="$5"
    local pattern="${6-$prefix[^ ]*$suffix}"
    local file="$prefix$version$suffix"

    ln -f "$file" "../downloads/$file"
    echo "${stagedir}/$dist_class/$file" >>../NEXT.${dist_class}.built
    gen_db_update "$dist_class" "https://www.caida.org/projects/spoofer/downloads/${file}"

    cat >../NEXT.${dist_class}.var <<-EOF
	dist_prefix="$prefix"
	dist_version="$version"
	dist_suffix="$suffix"
	dist_desc="$desc"
	dist_file="$file"
	dist_pattern="$pattern"
	dist_url="downloads/$file"
	EOF
}

update_web_pages() {
    (
        . ./NEXT.$1.var

        echo; echo "############## updating web pages for $1"
        assert test "$dist_version" = "$version"
        assert cd $webdir
        branch="spoofer-$dist_version${websuffix}"
        currentbranch=$(git rev-parse --abbrev-ref HEAD)
        if test "$currentbranch" != "$branch"; then
            assert git checkout main
            assert git pull
            assert git checkout -b "$branch"
        fi

        # replace filename in _index.md
        export replacement="|[${dist_file}](${dist_url})|${dist_desc}|"
        assert perl -MEnglish -pe 'if (/\|\['"${dist_pattern}"'\]\(([^|]*\|){2}/) { $_ = $PREMATCH . $ENV{"replacement"} . $POSTMATCH; }' $webcontent/_index.md >$webcontent/_index.md.tmp

        assert egrep -q "${dist_file}" $webcontent/_index.md.tmp
        assert mv $webcontent/_index.md.tmp $webcontent/_index.md

        # add new release to "Recent Updates" section and remove old release
        assert perl -ne "if (/<ul class=.recentupdates.>/) { print; print \"    <li><a href='#download-client-software'>Spoofer ${dist_version} released ($(date +%Y-%m))</a></li>\\n\"; } elsif (!/Spoofer [0-9.]* released/) { print; }" $webcontent/_index.md >$webcontent/_index.md.tmp
        assert egrep -q "Spoofer ${dist_version} released" $webcontent/_index.md.tmp
        assert mv $webcontent/_index.md.tmp $webcontent/_index.md
        assert git add $webcontent/_index.md

    ) || exit $?
}

gen_db_update() {
    local dist_class="$1"
    local file="$2"
    case $dist_class in
    src)
	local WHERE="Os IS NULL AND UpgradeKey IS NULL"
	;;
    *)
	local OS=$(sed -ne '/^#define OS "\(.*\)"/s//\1/p' config.h)
	local UPGRADE_KEY=$(sed -ne '/^#define UPGRADE_KEY "\(.*\)"/s//\1/p' config.h)
	test -n "$UPGRADE_KEY" || return; # no automatic upgrade, no db update
	assert test -n "$OS"
	local WHERE="Os='${OS}' AND UpgradeKey='${UPGRADE_KEY}'"
	;;
    esac
    NVERSION=$(sed -ne '/^#define NVERSION \(.*\)/s//\1/p' config.h)
    cat >../NEXT.${dist_class}.db <<-EOF
	    UPDATE ClientVersions SET CurVersion=${NVERSION}, VersionStr='${version}',
	    file='${file}'
	    WHERE ${WHERE};
	EOF
}

dump_next_steps() {
    echo '* locally:'
    if ls NEXT.*.local1 >/dev/null 2>&1; then
        cat $(ls -tr NEXT.*.local1)
    fi
    dists=$(echo $( (ls -1 NEXT.*.built) | cut -d. -f2))
    echo "    in '$(cd ..; pwd)'"
    echo "        ./release $(cat ./version) web"
    echo "    in '$webdir'"
    echo "        snap run hugo server -D [--bind 0.0.0.0]"
    echo "        # check http://$(hostname):1313/projects/spoofer"
    echo "        # kill hugo (optional)"
    echo "        git commit -m 'Release Spoofer $(cat ./version) for $dists' $webcontent $webstatic"
    echo "        git push --set-upstream origin spoofer-$(cat ./version)"
    echo "        # make merge request for branch spoofer-$(cat ./version)"
    echo "        # ask webmaster to push to production (?)"
    if ls NEXT.*.db >/dev/null 2>&1; then
        echo '* in "spoofer_test" and "spoofer_prod" databases:'
        cat $(ls -tr NEXT.*.db)
    fi
    if ls NEXT.*.local2 >/dev/null 2>&1; then
        echo '* locally:'
        cat $(ls -tr NEXT.*.local2)
    fi
}

while test "$1"; do
    option=""
    case "$1" in
    -[rsotwWc])
        [ $# -lt 2 ] && echo "Option $1 requires an argument" >&2 && exit 1
        option=$1
        optarg=$2
        shift; shift;;
    -[rsotwWc]*)
        option=$(echo "$1" | cut -c1-2)
        optarg=$(echo "$1" | cut -c3-)
        shift;;
    -u) signed="unsigned"; signprefix="unsigned-"; shift;;
    -F) forceversion="1"; shift;;
    -x) cd $stagedir; dump_next_steps; exit 0;;
    -h) usage; exit 0;;
    --) shift; break;;
    -*) echo "unknown option $1" >&2; usage; exit 1;;
    *) break;;
    esac
    case "$option" in
    -r) revision=$optarg;;
    -s) cs_dir=$optarg;;
    -o) CONFIG_OPTIONS="$CONFIG_OPTIONS $optarg";;
    -t) tarball="$optarg";;
    -w) webdir="$optarg";;
    -W) websuffix="$optarg";;
    -c) copyright="$optarg";;
    esac
done

version="$1"

test $# -ge 1 || { usage; exit 1; }
test -n "$version" || { usage; exit 1; }

shift

if test -z "$revision"; then
    revision="release-$(echo $version | sed 's/\./-/g')"
fi

dist_type_to_class() {
    case "$1" in
    ubuntu|ubuntu-*) echo ubuntu;;
    src|win32|mac|web) echo "${dist_type}";;
    *)
	echo "Error: unknown distibution type \"$dist_type\"" >&2
	exit 1
	;;
    esac
}

# check command line arguments
for dist_type in "$@"; do
    dist_type_to_class "$dist_type" >/dev/null
done

# make cs_dir absolute
cs_dir=$(cd "$cs_dir"; pwd;)

echo "# release version: $version"
echo "# release revision: $revision"
echo "# release types: $*"

if test $(umask) != "0022"; then
    echo "WARNING: umask is $(umask); normally it should be 0022." >&2
    echo "Press return to continue." >&2
    read line
fi

reuse=false
exportdir="spoofer-$revision"

if test -f $stagedir/version && test "$version" != $(cat $stagedir/version); then
    echo "ERROR: Version '$version' conflicts with $stagedir/version $(cat $stagedir/version)" >&2
    echo "Press return to delete existing $stagedir or interrupt to abort." >&2
    read line

elif test -d $stagedir/$exportdir; then
    echo "############## Found existing $stagedir/$exportdir"
    while true; do
	echo "\aType 'r' to reuse it, or 's' to start from scratch."
	read response
	case "$response" in
	    R|r) reuse=true; break;;
	    S|s) reuse=false; break;;
	    *) continue;;
	esac
    done
fi

if $reuse; then
    assert cd $stagedir/$exportdir
else
    echo "############## Exporting $stagedir/$exportdir"
    test -d $stagedir && chmod -R u+rw $stagedir
    assert rm -rf $stagedir
    assert mkdir $stagedir
    assert mkdir $stagedir/downloads
    echo "$version" >$stagedir/version
    abs_stagedir=$(cd $stagedir; pwd)

    # We need `git archive` for its handling of "export-*" gitattributes,
    # but it doesn't recurse submodules, so we must recurse manually.

    # First, create a worktree copy of $revision from the local repo.  (This
    # allows us to use a revision that may not exist in the origin, and is
    # more efficient than cloning from the origin).
    assert git worktree add --detach "$stagedir/worktree-$revision" $revision

    # Next, update submodules needed by $revision in the worktree created
    # above.  (Note: protocol.file.allow is needed to override a security
    # check apparently triggered by using a worktree; see
    # https://github.com/git/git/commit/a1d4f67c12.)
    (
    assert cd "$stagedir/worktree-$revision"
    assert git -c protocol.file.allow=always submodule update --init
    )

    # Next, export superproject and submodules from worktrees to stagedir.
    (
    assert cd "$stagedir/worktree-$revision"
    assert git archive --prefix $exportdir/ $revision | tar xf - -C"$abs_stagedir"
    assert git submodule foreach 'git archive --prefix "'"$exportdir"'/$displaypath/" $sha1 | tar xf - -C"'"$abs_stagedir"'"'
    )

    # Finally, clean up the worktree.
    git worktree remove --force "$stagedir/worktree-$revision"

    assert cd $stagedir/$exportdir
    case "$version" in
	*alpha*) cat README.alpha README >README.tmp && mv README.tmp README;;
    esac
fi

# example:  m4_define([SPOOFER_VERSION], [1.4.0-beta1])
cfgversion=$(sed -ne 's/^m4_define(\[SPOOFER_VERSION\], *\[\([^]]*\)\].*/\1/p' configure.ac)
if test "$forceversion" = "1"; then
    sed -e 's/^\(m4_define(\[SPOOFER_VERSION\], *\)\[\([^]]*\)\]/\1['"$version"']/' configure.ac >configure-forced.ac || exit $?
    echo "Forced version:"
    diff configure.ac configure-forced.ac
    mv configure-forced.ac configure.ac
elif test "x$cfgversion" != "x$version"; then
    echo "ERROR: configure.ac version '$cfgversion' does not match requested version '$version'."
    exit 1
fi


### sanity checks before we start the slow process of building releases

# sanity check: copyrights
for f in prober/spoofer-prober.cc manager/scheduler/main.cpp mac-scripts/apps/postinstall.in; do
    egrep -q "Copyright.*${copyright} The Regents of the University of California" $f || \
        { echo "Error: missing/old copyright in $f (use -c to force a different year)" >&2; exit 1; }
done

# sanity check: debian/copyright
egrep "The Regents of the University of California" debian/copyright>reg
assert egrep -q "${copyright} The Regents" reg
egrep -v "${copyright} The Regents" reg && \
    { echo "Error: out of date debian/copyright? (use -c to force a different year)" >&2; exit 1; }
rm reg


if test "$*" != "web"; then
    # we can skip this if not releasing anything other than "web"
    assert ./bootstrap
fi
assert cd .. ; # ${stagedir}

for dist_type in "$@"; do
    dist_class=$(dist_type_to_class "$dist_type")
    assert rm -f "NEXT.${dist_class}."*
    assert rm -rf ${dist_class}
    assert mkdir ${dist_class}
done


# Build the distributions
for dist_type in "$@"; do
    dist_class=$(dist_type_to_class "$dist_type")
    case $dist_class in
    src)
	echo; echo "############## building source distribution"
	assert cd src
	if test -z "$QMAKE"; then
	    for f in qmake; do
		if $f --version >/dev/null 2>&1; then QMAKE="$f"; break; fi
	    done
	fi
	if test -z "$PROTOC"; then
	    for f in protoc; do
		if $f --version >/dev/null 2>&1; then PROTOC="$f"; break; fi
	    done
	fi
	assert ../$exportdir/configure ${CONFIG_OPTIONS}
	# During "make dist", disable unneeded tools to catch unintended use.
        # Note: due to a bug introduced in automake 1.16.3, `make dist` will
        # incorrectly try to build BUILT_SOURCES, which requires PROTOC.  So
        # we must not disable PROTOC below.  (This could probably be avoided
        # with the "no-dist-built-sources" option to automake, but that was
        # broken when added in 1.16.4, and not fixed until 1.18.)
	assert make dist CXX='bad_CXX' QMAKE='bad_QMAKE'
	assert make distcheck DISTCHECK_CONFIGURE_FLAGS="${CONFIG_OPTIONS} \
	    PROTOC='$PROTOC' QMAKE='$QMAKE'"
	assert finish $dist_class spoofer- "$version" .tar.gz "Source Code"
	assert cd ..; # ${stagedir}

        # Docker
        DOCKER_USER=kenkeys
        cat >>NEXT.${dist_class}.local2 <<-EOF
	    in working copy of spoofer:
	        sudo docker build -t $DOCKER_USER/spoofer:latest -t $DOCKER_USER/spoofer:$VERSION spoofer-docker
	        sudo docker push $DOCKER_USER/spoofer:latest $DOCKER_USER/spoofer:$VERSION
	EOF

        # OpenWRT
	ver=$(echo "${version}" | sed -e 's/\./-/g')
	SUM=$(sha256sum src/spoofer-${version}.tar.gz | awk '{print $1}')
        echo "$SUM" | egrep -q '^[0-9a-f]{64}$' || \
            SUM="(###### FILL IN SHA256SUM OF spoofer-${version}.tar.gz ######)"
	cat >>NEXT.${dist_class}.local2 <<-EOF
	    in '~/openwrt/openwrt-packages' (a working copy of a fork of
	    https://github.com/openwrt/packages):
	        # see https://openwrt.org/submitting-patches
	        git fetch upstream
	        git checkout master
	        git merge upstream/master    ;# sync my copy with upstream
	        git push origin master       ;# and push to my fork on github
	        git checkout -b spoofer-${ver}  ;# create new branch
	        in net/spoofer/Makefile:
	            Copyright ${copyright}
	            PKG_VERSION:=${version}
	            PKG_RELEASE:=1
	            PKG_HASH:=${SUM}
	            # REMOVE "include vpath.mk"
	        # make any other necessary changes
	        git add net/spoofer/Makefile
	        git commit --signoff
	            spoofer: Update to ${version}
	        # if there are multiple commits since last release, squash them
	        git push --all
	        # make a pull request
	EOF

	;;

    ubuntu)
	# See: https://help.launchpad.net/Packaging/PPA/BuildingASourcePackage
	echo; echo "############## building ubuntu distribution"

	assert test "$(lsb_release -si)" = "Ubuntu"
	assert cd ubuntu

	case "$tarball" in
	    '') tarball=../src/spoofer-$version.tar.gz;;
	    /*) : nop ;;
	    *) tarball=../../$tarball;;
	esac
	assert tar zxf "$tarball"

	assert cd spoofer-$version
	(cd ../../..; git archive --prefix debian/ $revision:debian;) | tar xf -
	assert test -d debian

	cat >>../../NEXT.${dist_class}.local2 <<-EOF
	    in '$stagedir/ubuntu'
	        copy spoofer-$version/debian/changelog to a source tree and commit it
	        # If there are new ubuntu series, update your ~/.dput.cf
	EOF

	if test -n "$SPOOFER_RELEASE_BINARY"; then
	    all_series=$(lsb_release -sc)
	elif test -n "$SPOOFER_UBUNTU_SERIES"; then
	    all_series="$SPOOFER_UBUNTU_SERIES"
        else
            all_series=""
            ymd=$(date +"%Y-%m-%d")
            inrange() { ! test $1 '<' $2 && ! test $1 '>' $3; }
            add_series() { all_series="$all_series $*"; echo "all_series: $all_series"; }
            inrange $ymd 2022-04-21 2027-06-01 && add_series jammy; # LTS
            inrange $ymd 2024-04-25 2029-05-31 && add_series noble; # LTS
            inrange $ymd 2025-10-09 2026-07-09 && add_series questing;
            inrange $ymd 2026-04-23 2031-06-29 && add_series resolute; # LTS
            inrange $ymd 2026-10-99 9999-99-99 && {
                echo "Error: Don't know name of latest Ubuntu series.  Update release script." >&2; exit 1;
            }
	fi
	prev_series=""
	for series in $all_series; do
	    case $series in
		jammy)    ubuntu="ubuntu-22.04.1";;
		noble)    ubuntu="ubuntu-24.04.1";;
		questing) ubuntu="ubuntu-25.10.1";;
		resolute) ubuntu="ubuntu-26.04.1";;
		*) echo "unknown ubuntu series '$series'" >&2; exit 1;;
	    esac

	    if test -n "$prev_series"; then
		# Use the same debian/changelog, just change the series name
                # (Launchpad requires the correct series name in the changelog;
                # an override in dput.cf isn't sufficient.)
		sed -i -e "1s/~ubuntu.*) $prev_series;/~$ubuntu) $series;/" \
		    debian/changelog
            elif test "${dist_type}" = "ubuntu"; then
		# Use a default log message
		assert debchange -p -v "$version-1~$ubuntu" -D "$series" "New upstream release."
            else # "ubuntu-N"
		# Prompt for a new log message
                N=${dist_type#ubuntu-}
		assert debchange -p -v "$version-${N}~$ubuntu" -D "$series"
	    fi
	    PPA_VERSION=$(sed -ne '1s/spoofer (\(.*\)).*/\1/p' debian/changelog)
	    ORIG_VERSION=$(echo $PPA_VERSION | sed -e 's/-[0-9.]*$//')
	    if ! test -L ../spoofer_${ORIG_VERSION}.orig.tar.gz; then
		assert ln -s "$tarball" ../spoofer_${ORIG_VERSION}.orig.tar.gz
	    fi

	    # Note: to check dependencies, build in a clean chroot environment
	    # with: `pdebuild --buildresult ..`
            # Note: if running remotely without a GUI, but debuild is timing
            # out in gpg, it may be giving a GUI prompt on another screen
            # where you can't answer.  Try forcing it to use tty:
            # > sudo apt install pinentry-tty
            # > sudo update-alternatives --config pinentry
            #   (then select pinentry-tty)
	    if test -n "$SPOOFER_RELEASE_BINARY"; then
		assert debuild -i -us -uc -b
	    else
		assert debuild -S
	    fi

	    echo "${stagedir}/ubuntu/spoofer_${PPA_VERSION}"'*' >>../../NEXT.${dist_class}.built
	    cat >>../../NEXT.${dist_class}.local2 <<-EOF
	        dput spoofer-$series spoofer_${PPA_VERSION}_source.changes
		EOF
	    prev_series="$series"
	done
	cd ..; # ubuntu

        cat >../NEXT.${dist_class}.var <<-EOF
		dist_prefix="Spoofer-"
		dist_version="$version"
		dist_suffix=" PPA"
		dist_desc="Ubuntu packages for: $all_series (signed)"
		dist_file="Spoofer-$version PPA"
		dist_pattern="Spoofer-[^ ]* PPA"
		dist_url="https://launchpad.net/~spoofer-dev/+archive/ubuntu/spoofer"
		EOF

	cd ..; # $stagedir
	;;

    win32)
	echo; echo "############## building $signed Windows binary distribution"
	assert cd win32
	assert cp $HOME/packages/WinPcap_4_1_3.exe ../$exportdir/win-bin
	assert cp $HOME/packages/vc2012u4redist_x86.exe ../$exportdir/win-bin
	(
	    PATH=/opt/mxe/usr/bin:$PATH
	    assert ../$exportdir/configure ${CONFIG_OPTIONS} \
		--host=i686-w64-mingw32.static \
		UPGRADE_KEY="https://www.caida.org/" \
		CXXFLAGS="-O2 -DNDEBUG" \
		PROTOC='/opt/mxe/usr/x86_64-pc-linux-gnu/bin/protoc'
	    assert make CS_DIR="$cs_dir" windist-${signed}
	) || exit $?
	assert finish $dist_class ${signprefix}Spoofer- "$version" -win32.exe "Windows Binary Installer (signed)"
	assert cd ..; # ${stagedir}
	;;

    mac)
	echo; echo "############## building $signed macOS binary distribution"
	assert test $(uname) = "Darwin"
	assert cd mac
	(
	    export MACOSX_DEPLOYMENT_TARGET=10.13
	    # where to find headers/libraries/tools/etc for deployment target
	    TARGETROOT="$HOME/macos-$MACOSX_DEPLOYMENT_TARGET"
	    # set PATH for protoc, productsign, qmake
	    PATH="$TARGETROOT/bin:$PATH"
	    assert ../$exportdir/configure \
		--with-openssl="$TARGETROOT" \
		${CONFIG_OPTIONS} \
		UPGRADE_KEY="https://www.caida.org/" \
		CXX='clang++ -stdlib=libc++' \
		CXXFLAGS="-arch x86_64 -O2 -I$TARGETROOT/include -DNDEBUG" \
		LDFLAGS="-arch x86_64 -L$TARGETROOT/lib"
		# PKG_CONFIG_PATH="$TARGETROOT/lib/pkgconfig" # not needed
	    assert make macdist-${signed}
	) || exit $?
	assert finish $dist_class ${signprefix}Spoofer- "$version" -macos.pkg "macOS Binary Installer (signed)" 'Spoofer-[^ ]*-macosx?.pkg'
	assert cd ..; # ${stagedir}
	;;

    web)
        # ignore at this step
        ;;

    *)
	# shouldn't happen
	echo "############## unknown distibution class \"$dist_class\"" >&2
	exit 1
	;;
    esac
done


# Update web tree
for dist_type in "$@"; do
    dist_class=$(dist_type_to_class "$dist_type")
    case $dist_class in
    src|ubuntu|win32|mac)
        # ignore at this step
        ;;

    web)
        case "$dist_version" in
        *alpha*|*beta*)
            echo "Skipping web update for alpha or beta version"
            ;;
        *)
            if ! test -d "$webdir" && test $(hostname) != "$homebox"; then
                cat <<-EOF
		    You have no "$webdir" and this is not your home box ($homebox).
		    To continue the release process, do:
		        scp -r $stagedir/NEXT.* $stagedir/downloads $homebox:spoofer/spoofer-client-server/$stagedir
		    Then, on $homebox:spoofer/spoofer-client-server, you can do:
		        ./release [<options>] $version web
		EOF
            else
                # web pages
                dists=$(echo $( (ls -1 NEXT.*.built) | cut -d. -f2))
                for dist in $dists; do
                    update_web_pages "$dist"
                done
                # downloads
                echo; echo "############## updating web downloads"
                for file in downloads/*; do
                    assert cp "$file" "$webdir/$webstatic/$file"
                    assert git -C $webdir add "$webstatic/$file"
                done
                # changelog
                echo; echo "############## updating web changelog"
                assert cp "$exportdir/CHANGES" "$webdir/$webstatic/downloads/changelog.txt"
                assert git -C $webdir add "$webstatic/downloads/changelog.txt"
                git -C $webdir status
            fi
            ;;
        esac
        ;;
    esac
done


echo; echo

assert ls NEXT.*.built >/dev/null 2>&1

echo "Successfully built releases:"
cat $(ls -tr NEXT.*.built)

echo
case "$version" in
*alpha*|*beta*)
    echo 'If this were a production release, the next steps would be:'
    ;;
*)
    echo 'Next steps:'
    ;;
esac
dump_next_steps
