#!/bin/bash -e

ARGS=$(getopt -o r:h -l remote-name: -l help -n "$0" -- "$@")
eval set -- "$ARGS"

REMOTE_NAME=

function usage {
    cat <<EOF
Usage:
    $0 [-h] [-r REMOTE_NAME] STAGE [PASSWORD]
Arguments:
    STAGE     One of the following:
                - dev: development staging (requires password)
                - demo: beta testing in advance of production releases
                - prod: full production releases for general availability
    PASSWORD  Development password (for staging branch only)

Options:
    -r, --remote-name REMOTE_NAME  Name of the flatpak remote to stage; if
                                   unspecified, all remotes configured in the
                                   system repository will be staged
    -h, --help                     Show this message
EOF
}

while true; do
    case "$1" in
        -r|--remote-name)
            shift
            REMOTE_NAME="$1"
            shift
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        --)
            shift
            break
            ;;
    esac
done

if [ $# -lt 1 ] || [ $# -gt 2 ] ; then
    if [ $# -lt 1 ] ; then
        echo "Error: missing STAGE argument" >&2
    else
        echo "Error: extra arguments after STAGE PASSWORD" >&2
    fi
    echo >&2
    usage >&2
    exit 1
fi

STAGE="$1"

PASSWORD=
if [ $# -ge 2 ] ; then
    PASSWORD="$2"
fi

if [ $EUID != 0 ] ; then
    echo "Program requires superuser privileges" >&2
    exit 1
fi

if [ "$STAGE" == "dev" ] ; then
    if [ -z "$PASSWORD" ] ; then
	echo "Error: missing required PASSWORD for dev stage" >&2
	exit 1
    fi
    base_url="https://endless:${PASSWORD}@ostree.endlessm.com/staging/dev"
elif [ "$STAGE" == "demo" ] ; then
    base_url="https://ostree.endlessm.com/staging/demo"
elif [ "$STAGE" == "prod" ] ; then
    base_url="https://ostree.endlessm.com/ostree"
else
    echo "Invalid STAGE -- must be dev, demo, or prod" >&2
    exit 1
fi

if [ -d /var/endless-extra/flatpak/repo ]; then
    flatpak_repo=/var/endless-extra/flatpak/repo
else
    flatpak_repo=/var/lib/flatpak/repo
fi

remote_found=
for remote in `flatpak remote-list --system | awk {'print $1'}` ; do
    if [ -n "$REMOTE_NAME" ]; then
        if [ "$remote" != "$REMOTE_NAME" ]; then
            continue
        else
            remote_found=true
        fi
    fi

    url=$(ostree --repo="$flatpak_repo" config get --group 'remote "'"$remote"'"' 'url')
    if [[ "$url" == *"ostree.endlessm.com"* ]] ; then
        repo=${url##*/}
        new_url="${base_url}/${repo}"
        if [ "$remote" == "eos-sdk" ] && [ "$STAGE" == "dev" ] ; then
            # eos-sdk's dev is passwordless
            new_url="https://ostree.endlessm.com/staging/dev/${repo}"
        fi
        echo "Setting flatpak $remote URL to $new_url"
        flatpak remote-modify "$remote" --url="$new_url"

        # Update the collection ID if it's set
        collection_id=$(ostree --repo="$flatpak_repo" config get --group 'remote "'"$remote"'"' 'collection-id' 2>/dev/null || echo "")
        if [ -n "$collection_id" ] ; then
            # For info on the collection ID patterns, see
            # https://phabricator.endlessm.com/w/software/ostree/infrastructure/#repository-stages
            if [ "$STAGE" == "prod" ] ; then
                # change e.g. com.endlessm.Dev.Apps → com.endlessm.Apps or com.endlessm.Demo.Apps → com.endlessm.Apps
                new_collection_id=`echo "$collection_id" | sed -e "s/Dev\.//" | sed -e "s/Demo\.//"`
            elif [ "$STAGE" == "dev" ] ; then
                # change e.g. com.endlessm.Demo.Apps → com.endlessm.Dev.Apps or com.endlessm.Apps → com.endlessm.Dev.Apps
                new_collection_id=`echo "$collection_id" | sed -e "s/Dev\.//" | sed -e "s/Demo\.//" | sed -e "s/com\.endlessm\./com.endlessm.Dev./"`
            elif [ "$STAGE" == "demo" ] ; then
                # change e.g. com.endlessm.Dev.Apps → com.endlessm.Demo.Apps or com.endlessm.Apps → com.endlessm.Demo.Apps
                new_collection_id=`echo "$collection_id" | sed -e "s/Dev\.//" | sed -e "s/Demo\.//" | sed -e "s/com\.endlessm\./com.endlessm.Demo./"`
            else
                echo "Unrecognized stage '$STAGE'"
                exit 1
            fi

            flatpak remote-modify --collection-id="$new_collection_id" "$remote"
        fi

        # Delete the appstream data and fetch it for the new remote;
        # otherwise an update might be rejected as a downgrade
        # https://github.com/flatpak/flatpak/issues/1615#issuecomment-385133763
        rm -rf "$(dirname $flatpak_repo)/appstream/$remote"
        for arch in `flatpak --supported-arches`; do
            ostree --repo="$flatpak_repo" refs --delete "$remote:appstream/$arch" "$remote:appstream2/$arch"
            # This might fail for the secondary architecture
            flatpak update --appstream --arch="$arch" "$remote" >/dev/null 2>&1 || true
        done

        # Do the same with ostree-metadata
        # https://github.com/flatpak/flatpak/issues/1477#issuecomment-372167938
        ostree --repo="$flatpak_repo" refs --delete "$remote:ostree-metadata"
        # Try to update ostree-metadata, but don't bail on failure
        flatpak remote-ls "$remote" >/dev/null || true
    fi
done

if [ -n "$REMOTE_NAME" ] && [ -z "$remote_found" ]; then
    echo "Could not find remote $REMOTE_NAME" >&2
    exit 1
fi
