#!/usr/bin/env bash
#
# Fetch the latest release version of a GitHub repository in tar.gz format (e.g. v1.0.0.tar.gz)
# Usage: x-gh-get-latest-release-targ <repo> [--get]
# Author: Ismo Vuorinen <https://github.com/ivuorinen> 2024

set -euo pipefail

# Enable verbosity with VERBOSE=1
VERBOSE="${VERBOSE:-0}"

# Function to print usage information
usage()
{
  echo "Usage: $0 <github repo> [--get] (e.g. ivuorinen/dotfiles)"
  echo "  --get: Download and extract the tarball"
  exit 1
}

# Function to print messages if VERBOSE is enabled
# $1 - message (string)
msg()
{
  [[ "$VERBOSE" -eq 1 ]] && echo "$1"
  return 0
}

# Function to fetch the tarball URL of the latest release from GitHub
# $1 - GitHub repository (string)
get_latest_tarball_url()
{
  local repo=$1

  local tarball_url
  tarball_url=$(curl -s "https://api.github.com/repos/${repo}/releases/latest" \
    | sed -Ene '/^[[:blank:]]+"tarball_url":[[:blank:]]"(https:[^"]+)",/s//\1/p')

  if [ -z "$tarball_url" ]; then
    echo "(!) Failed to fetch the tarball URL for repository: $repo"
    exit 1
  fi

  echo "$tarball_url"
  return 0
}

# Function to download and extract the tarball
# $1 - tarball URL (string)
download_and_extract()
{
  local url="$1"

  msg "Downloading and extracting from: $url"
  curl --location --silent "$url" | tar --extract --gzip --file=- || {
    echo "(!) Failed to download or extract the tarball."
    exit 1
  }

  return 0
}

# Main function
main()
{
  if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
    usage
  fi

  local repo=$1
  local get_tarball=false

  if [ "$#" -eq 2 ]; then
    # Check if the first or second argument is --get
    if [ "$1" == "--get" ] || [ "$2" == "--get" ]; then
      get_tarball=true
    else
      usage
    fi
  fi

  # Check if the first argument is --get
  if [ "$1" == "--get" ]; then
    repo="$2"
  fi

  msg "Fetching the tarball URL for the latest release of repository: $repo"

  local location
  location=$(get_latest_tarball_url "$repo")

  if $get_tarball; then
    download_and_extract "$location"
  else
    echo "$location"
  fi

  return 0
}

main "$@"

# vim: set ts=2 sw=2 ft=sh et:
