#!/bin/bash
set -e

for arg in "$@"; do
    case "$arg" in
    --dry-run) DRY_RUN=1 ;;
    --no-github) NO_GITHUB=1 ;;
    --no-codeberg) NO_CODEBERG=1 ;;
    --no-flowcontrol) NO_FLOWCONTROL=1 ;;
    --no-aur) NO_AUR=1 ;;
    --no-manifest) NO_MANIFEST=1 ;;
    --no-build) NO_BUILD=1 ;;
    --allow-dirty)
        ALLOW_DIRTY=1
        NO_GITHUB=1
        NO_CODEBERG=1
        NO_FLOWCONTROL=1
        NO_AUR=1
        NO_MANIFEST=1
        ;;
    esac
done

builddir="nightly-build"

DESTDIR="$(pwd)/$builddir"
BASEDIR="$(cd "$(dirname "$0")/.." && pwd)"
APPNAME="$(basename "$BASEDIR")"
title="$APPNAME nightly build"
repo="neurocyte/$APPNAME-nightly"

release_notes="$BASEDIR/$builddir-release-notes"

cd "$BASEDIR"

if [ -z "$NO_BUILD" ]; then
    if [ -e "$DESTDIR" ]; then
        echo directory \"$builddir\" already exists
        exit 1
    fi

    if [ -e "$release_notes" ]; then
        echo file \""$release_notes"\" already exists
        exit 1
    fi
fi

DIFF="$(git diff --stat --patch HEAD)"

if [ -z "$ALLOW_DIRTY" ] && [ -z "$NO_BUILD" ]; then
    if [ -n "$DIFF" ]; then
        echo there are outstanding changes:
        echo "$DIFF"
        exit 1
    fi

    UNPUSHED="$(git log --pretty=oneline '@{u}...')"

    if [ -n "$UNPUSHED" ]; then
        echo there are unpushed commits:
        echo "$UNPUSHED"
        exit 1
    fi
fi

# get latest version tag

if [ -z "$NO_FLOWCONTROL" ] || [ -n "$ALLOW_DIRTY" ]; then
    last_nightly_version=$(tea api --login flow-control "repos/neurocyte/flow-nightly/releases/latest" | jq -r .tag_name)
elif [ -z "$NO_GITHUB" ]; then
    last_nightly_version=$(tea api --login codeberg "repos/neurocyte/flow-nightly/releases/latest" | jq -r .tag_name)
elif [ -z "$NO_CODEBERG" ]; then
    last_nightly_version=$(curl -s https://codeberg.org/api/v1/repos/neurocyte/flow-nightly/releases/latest | jq -r .tag_name)
fi
[ -z "$last_nightly_version" ] && {
    echo "failed to fetch $title latest version"
    exit 1
}

local_version="$(git --git-dir "$BASEDIR/.git" describe)"
if [ -z "$NO_BUILD" ]; then
    if [ "$local_version" == "$last_nightly_version" ]; then
        echo "$title is already at version $last_nightly_version"
        exit 1
    fi
fi

if [ -z "$NO_BUILD" ]; then

    echo
    echo "building $title version $local_version... (previous $last_nightly_version)"
    echo
    git log "${last_nightly_version}..HEAD" --pretty="format:neurocyte/$APPNAME@%h %s"
    echo
    echo running tests...

    contrib/builder/build test

    if [ -n "$DRY_RUN" ]; then
        echo 'building (dry-run)...'
        contrib/builder/build -Dall-targets --release
        exit 0
    fi

    echo building...

    contrib/builder/build -Dall-targets --release --prefix "./$builddir/build"

    VERSION=$(/bin/cat "$DESTDIR/build/version")

    git archive --format=tar.gz --output="$DESTDIR/flow-$VERSION-source.tar.gz" HEAD
    git archive --format=zip --output="$DESTDIR/flow-$VERSION-source.zip" HEAD
    tar -zcf "$DESTDIR/flow-$VERSION-source-dependecies.tar.gz" zig-pkg/builder

    cd "$DESTDIR/build"

    TARGETS=$(/bin/ls)

    for target in $TARGETS; do
        if [ -d "$target" ]; then
            cd "$target"
            if [ "${target:0:8}" == "windows-" ]; then
                echo packing zip "$target"...
                zip -r "../../${APPNAME}-${VERSION}-${target}.zip" ./*
                cd ..
            else
                echo packing tar "$target"...
                tar -czf "../../${APPNAME}-${VERSION}-${target}.tar.gz" -- *
                cd ..
            fi
        fi
    done

    cd ..
    rm -r build

    if [ -n "$NO_CODEBERG" ] && [ -n "$NO_GITHUB" ]; then
        echo "skipping version manifest: neither download mirror will be updated"
        NO_MANIFEST=1
    fi
    if [ -z "$NO_MANIFEST" ]; then
        "$BASEDIR/contrib/publish_version_manifest" sign --nightly "$VERSION"
    fi

    TARFILES=$(/bin/ls)

    for tarfile in $TARFILES; do
        echo signing "$tarfile"...
        gpg --local-user 4E6CF7234FFC4E14531074F98EB1E1BB660E3FB9 --detach-sig "$tarfile"
        sha256sum -b "$tarfile" >"${tarfile}.sha256"
    done

    echo "done making $title $VERSION @ $DESTDIR"
    echo

    /bin/ls -lah

    cd ..

    {
        echo "## commits in this build"
        echo
        git log "${last_nightly_version}..HEAD" --pretty="format:neurocyte/$APPNAME@%h %s"
        echo
        echo

        echo "## contributors"
        git shortlog -s -n "${last_nightly_version}..HEAD" | cut -b 8-
        echo

        echo "## downloads"
        echo "[flow-control.dev](https://git.flow-control.dev/neurocyte/flow-nightly/releases/tag/$VERSION) (source only)"
        echo "[github.com](https://github.com/neurocyte/flow-nightly/releases/tag/$VERSION) (binaries & source)"
        echo "[codeberg.org](https://codeberg.org/neurocyte/flow-nightly/releases/tag/$VERSION) (binaries & source)"
    } >"$release_notes"

    cat "$release_notes"

    if [ -n "$ALLOW_DIRTY" ]; then
        ls -la "$DESTDIR"/*
        echo
        echo build complete, no uploading for --allow-dirty builds.
        exit 0
    fi

    if [ -z "$NO_AUR" ]; then
        echo preparing upload to arch linux AUR
        git clone ssh://aur@aur.archlinux.org/flow-control-nightly-bin
        cd flow-control-nightly-bin
        PKGVER=${VERSION#v}
        sed -i "s/^pkgver=.*/pkgver=${PKGVER//-/.}/" PKGBUILD
        makepkg --printsrcinfo >.SRCINFO
        git commit -a -m "$title $VERSION"
        cd ..
    fi

else

    VERSION=$(/bin/cat "$BASEDIR/version-manifest/version-latest-nightly")

fi

ASSETS=""

if [ -z "$NO_FLOWCONTROL" ]; then
    ASSETS="$ASSETS --asset $DESTDIR/flow-${VERSION}-source.tar.gz"
    ASSETS="$ASSETS --asset $DESTDIR/flow-${VERSION}-source.tar.gz.sig"
    ASSETS="$ASSETS --asset $DESTDIR/flow-${VERSION}-source.tar.gz.sha256"
    ASSETS="$ASSETS --asset $DESTDIR/flow-${VERSION}-source.zip"
    ASSETS="$ASSETS --asset $DESTDIR/flow-${VERSION}-source.zip.sig"
    ASSETS="$ASSETS --asset $DESTDIR/flow-${VERSION}-source.zip.sha256"
    echo uploading to git.flow-control.dev
    tea releases create --login flow-control --repo "$repo" --tag "$VERSION" --title "$title $VERSION" --note-file "$release_notes" \
        $ASSETS
fi

if [ -z "$NO_CODEBERG" ]; then
    for a in "$DESTDIR"/*; do
        ASSETS="$ASSETS --asset $a"
    done
    echo uploading to codeberg.org
    tea releases create --login codeberg --repo "$repo" --tag "$VERSION" --title "$title $VERSION" --note-file "$release_notes" \
        $ASSETS
fi

if [ -z "$NO_GITHUB" ]; then
    echo uploading to github.com
    gh release create "$VERSION" --repo "$repo" --title "$title $VERSION" --notes-file "$release_notes" "$DESTDIR"/*
fi

if [ -z "$NO_AUR" ]; then
    echo uploading to arch linux AUR
    cd flow-control-nightly-bin
    git push
    cd ..
fi

if [ -z "$NO_MANIFEST" ]; then
    "$BASEDIR/contrib/publish_version_manifest" publish --nightly "$VERSION"
fi
