#!/usr/bin/env bash
# vim:et:ts=2:sts=2:sw=2

set -e

say() { echo "[admin] # $*"; }
run() {
  echo "[admin] $ $*"
  "$@"
}
err() { echo "[admin][ERROR] $*" >&2; }

if [ -z "$IS_GITLAB_CI_ENV" ]; then
  echo "This script is for gitlab only" >"/dev/stderr"
  exit 1
fi

say "Configuring bastion access"
{
  echo "$BASE64_BASTION_SSH_KEY" | base64 -d >"bastion_key"
  run chmod 0600 "bastion_key"

  eval $(ssh-agent -s)
  echo "$BASE64_BASTION_SSH_KEY" | base64 -d | tr -d '\r' | ssh-add -

  run mkdir -p ~/.ssh
  run ssh-keyscan gitlab.com >>~/.ssh/known_hosts
}

say "Configuring git access"
{
  run git remote remove origin || true
  run git remote add origin "git@gitlab.com:techlit-africa/admin.git"

  run git fetch origin
  # run git fetch --tags

  git config --global user.email "techlit-ci@techlit"
  git config --global user.name "Auto CI"
}

# CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
CURRENT_BRANCH="${CI_COMMIT_BRANCH:-}"

# tags
if [ -z "$CURRENT_BRANCH" ] && [ -n "$CI_COMMIT_TAG" ]; then
  CURRENT_BRANCH="main"
fi

if [ "$CURRENT_BRANCH" = "beta" ]; then
  say "Auto-tagging beta version..."
  LATEST_TAG=$(git tag -l | sort -V | tail -n1)
  if [ -z "$LATEST_TAG" ]; then
    VERSION="0.1.0-beta-1"
  elif [[ "$LATEST_TAG" == *"-beta-"* ]]; then
    VERSION=$(echo "$LATEST_TAG" | awk -F'beta-' '{print $1"beta-"($2+1)}')
  else
    BASE_VERSION=$(echo "$LATEST_TAG" | awk -F. '{$NF = $NF + 1;} 1' | sed 's/ /./g')
    VERSION="$BASE_VERSION-beta-1"
  fi
  say "New beta version: $VERSION"
  run git tag "$VERSION" -m "Release $VERSION"
  say "Pushing new tag to origin"
  run git push --tags
elif [ "$CURRENT_BRANCH" = "main" ]; then
  say "Checking for existing tag on current commit of main branch..."
  TAGS_ON_HEAD=$(git tag --points-at HEAD)
  if [ -z "$TAGS_ON_HEAD" ]; then
    err "Current commit on main branch is not tagged. Exiting as per rules."
    exit 1
  fi
  # Assuming only one tag per commit for simplicity, or taking the first one
  VERSION=$(echo "$TAGS_ON_HEAD" | head -n1)
  say "Building main branch from existing tag: $VERSION"
else
  err "This script is only for 'main' or 'beta' branches. Current branch is '$CURRENT_BRANCH'."
  exit 1
fi

TMPDIR=$(mktemp -d)
trap 'rm -rf -- "$TMPDIR"' EXIT

PACKAGE_DIR="$TMPDIR/package"
ARCHIVE_FILE="$TMPDIR/v$VERSION.tar.gz"
CHECKSUM_FILE="$TMPDIR/v$VERSION.sha256"

say "Creating package for version $VERSION in $TMPDIR"
{
  run mkdir -p "$PACKAGE_DIR"

  run cp -r . "$PACKAGE_DIR"
  run rm -rf "$PACKAGE_DIR"/{.git,.gitlab-ci.yml,README.md,bastion_key} || true
}

say "Generating changelog and Version file"
{
  echo "Version $VERSION"
  PREVIOUS_TAG=$(git tag -l | sort -V | grep -B1 "$VERSION" | head -n1)
  if [ -n "$PREVIOUS_TAG" ]; then
    git --no-pager log --pretty=format:'''- %s (%an)''' "$PREVIOUS_TAG..$VERSION"
  else
    git --no-pager log --pretty=format:'''- %s (%an)''' "$VERSION"
  fi
} >"$PACKAGE_DIR/.changelog"
echo "$VERSION" >"$PACKAGE_DIR/.version"

say "Creating tarball and checksum"
run tar -czf "$ARCHIVE_FILE" -C "$PACKAGE_DIR" .
(cd "$TMPDIR" && sha256sum "v$VERSION.tar.gz" >"v$VERSION.sha256")

# Upload directory depends on branch
if [ "$CURRENT_BRANCH" = "beta" ]; then
  DEST="/srv/admin-beta"
else
  DEST="/srv/admin"
fi

say "Uploading release"
{
  run scp -i "bastion_key" \
    -o UserKnownHostsFile=/dev/null \
    -o StrictHostKeyChecking=no \
    "$ARCHIVE_FILE" "$CHECKSUM_FILE" "gitlab@artix.techlitafrica.org:$DEST"
}
