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

# Get absolute repository root (especially when symlinked)
ROOT="$(realpath "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")")"

# Load accompanying bash library
source "$ROOT/lib/lib.bash"

COMMIT_MSG="$2"

if [ -n "$HELP" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
  say "
  USAGE:
    $(g "${BASH_SOURCE##*/}")  [$(c version)] [$(c commit message)]

  DESCRIPTION:
    $(g "${BASH_SOURCE##*/}") creates a new clone-able archive
    of the TechLit system hosted in BTRFS volume at $(c btrfs-path)
                                        (default: $(c /var/btrfs))

    The lastest snapshot version will be used by default
"
  exit 1
fi

# Exit now if run as root user
assert-is-user

say "This script will need root access via $(c sudo)"
sudo echo thank you

# Determine target component: desktop (default) or desktop-mini (MINI=true).
# A standard (large-storage) computer can bake mini images by setting MINI=true,
# e.g. after (.tl-branch-minify && reboot): MINI=true tl-img-pack
MINI="${MINI:-false}"
if [ "$MINI" = true ]; then
  COMP="desktop-mini"
  ARCH_DIR="/srv/desktop-mini"
else
  COMP="desktop"
  ARCH_DIR="/srv/desktop"
fi

say "Syncing $(c "$COMP") & snapshot versions"
{
  "$ROOT/bin/tl-comp-sync" "$COMP"
  "$ROOT/bin/tl-comp-sync" snapshots
}

# The patch version -- x.x.x
PATCH="${1:-"$("$ROOT/bin/tl-comp-latest" snapshots)"}"
# The minor version -- x.x.0
MINOR="$(echo "$PATCH" | cut -d. -f-2).0"
# The major version -- x.0.0
MAJOR="$(echo "$PATCH" | cut -d. -f-1).0.0"

# Snapshots directory
SNAP="/srv/snapshots"
# Directory for packing tarball
PACKDIR="${PACKDIR:-"$SNAP/v$PATCH.d.tmp"}"
# Changelog file
CHANGELOG="v$PATCH.changelog"

assert_parent() {
  local ver="$1"

  if ! [ -d "$SNAP/v$ver.d/@root" ] || ! [ -d "$SNAP/v$ver.d/@guest" ]; then
    err ""
    err "Snapshot v$(c "$ver") is not available locally."
    err ""
    err "Maybe you meant to create it instead?"
    err "  $(g tl-img-save) $(c "$ver")"
    err ""
    exit 1
  fi
}
say "Checking that parent snapshots exist"
{
  if [ "$PATCH" != "$MAJOR" ]; then assert_parent "$MAJOR"; fi
  if [ "$PATCH" != "$MINOR" ]; then assert_parent "$MINOR"; fi
}

say "Serializing snapshots"
{
  run sudo mkdir -p "$PACKDIR"

  run root-write "$PACKDIR/$CHANGELOG" "# TechLit Desktop v$PATCH Changelog
$COMMIT_MSG
"
  [ -z "$COMMIT_MSG" ] && run sudo "${EDITOR:-vim}" "$PACKDIR/$CHANGELOG"

  for subvol in @root @guest; do
    if [ "$PATCH" = "$MAJOR" ]; then
      run sudo btrfs send -f "$PACKDIR/$subvol.btrfs" "$SNAP/v$PATCH.d/$subvol"
    elif [ "$PATCH" = "$MINOR" ]; then
      run sudo btrfs send -f "$PACKDIR/$subvol.btrfs" -p "$SNAP/v$MAJOR.d/$subvol" "$SNAP/v$PATCH.d/$subvol"
    else # "$PATCH" = "$PATCH"
      run sudo btrfs send -f "$PACKDIR/$subvol.btrfs" -p "$SNAP/v$MINOR.d/$subvol" "$SNAP/v$PATCH.d/$subvol"
    fi
  done
}

say "Packing $(c "$COMP") v$PATCH..."
run sudo tar -C "$PACKDIR" -czvf "$ARCH_DIR/v$PATCH.tar.gz.tmp" "."

say "Moving $(c "v$PATCH") into $(c "$(basename "$ARCH_DIR")") component"
{
  run sudo mv "$ARCH_DIR/v$PATCH.tar.gz"{.tmp,}
  run sudo mv "$PACKDIR/$CHANGELOG" "$ARCH_DIR/$CHANGELOG"
  (
    cd "$ARCH_DIR" \
      && run sudo sha256sum "v$PATCH".{changelog,tar.gz} >"v$PATCH.sha256"
  )

  run sudo chown "$(id -u):$(id -g)" "$ARCH_DIR/v$PATCH"*
  run sudo chmod 0644 "$ARCH_DIR/v$PATCH".changelog
  run sudo rm -r "$PACKDIR"
}

say "Syncing $(c "$COMP") & snapshot versions"
{
  "$ROOT/bin/tl-comp-sync" "$COMP"
  "$ROOT/bin/tl-comp-sync" snapshots
}

say "Done."
