#!/bin/bash

# ABSTRACT: generates/updates sets in /etc/portage/sets for helping dev-lang/perl upgrades

source "${LIBDIR}/core-functions.sh" || exit 1;

set_suffix=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    "--quiet")
      export GENTOO_PERL_HELPERS_QUIETNESS=10
      shift
      ;;
    "--suffix")
      shift;
      set_suffix="$1";
      shift;
      ;;
    "--suffix="*)
      set_suffix="${1##--suffix=}"
      shift;
      ;;
    *)
      [[ -z "${1}"  || "${1:0:1}" == "-" ]] && die "Unknown argument ${1}"
      if [[ -z "${subslot}" ]]; then
        subslot="$1"
        shift
      else if [[ -z "${destsubslot}" ]]; then
          destsubslot="$1"
          shift
        else
          die "Excess argument $1"
        fi
      fi ;;
  esac
done

[[ -z "${subslot}" || -z "${destsubslot}" ]] && die "Expected ${cmdname} [previous-perl-version] [wanted-version]"

set -euo pipefail

sets="${ETC_PORTAGE_SETS:-${ETC_PORTAGE:-/etc/portage}/sets}"
cleanup="${sets}/perl-cleanup${set_suffix}"
upgrade="${sets}/perl-upgrade${set_suffix}"
perl_target="$(dorun print-matching-abi "${destsubslot}")"

mkdir -p "${sets}"    || die "Cannot ensure ${sets} directory exists"
touch -m "${cleanup}" || die "Cannot write ${cleanup}"
touch -m "${upgrade}" || die "Cannot write ${upgrade}"

einfo "Generating ${cleanup}"
(
  dorun installed-perl-core || einfo "No perl-core to clean"
  dorun installed-match-atom-blacklisted "${perl_target}" || einfo "No cruft virtuals to clean"
) | sort -u >"${cleanup}"
einfo "... Done ${cleanup}"

einfo "Generating ${upgrade}"

(
  dorun installed-deps-perl-subslot-rebuild "${destsubslot}" | grep -v '^perl-core/' ||\
    die "No packages detected needing recompilation against ${perl_target}, perhaps you've already upgraded to it?"
  dorun installed-perl-virtuals
) | grep -vxFf "${cleanup}" | sort -u >"${upgrade}" || die "Error generating rebuild list"

einfo "... Done ${upgrade}"

einfo "Created set @perl-cleanup${set_suffix} in ${cleanup}"
einfo "Created set @perl-upgrade${set_suffix} in ${upgrade}"
einfo
einfo "Assuming both of those were in /etc/portage/sets you can now do"
einfo "  emerge -va1 -k n @perl-upgrade${set_suffix}"
einfo "And if this exhibits confusing blockers that only refer to perl-core"
einfo "  emerge -C -va @perl-cleanup${set_suffix}"
einfo "Should help pave the way forward"
einfo
einfo "If portage crashes mid-way through an upgrade, after any relevant issues"
einfo "Re-run this tool to regenerate the sets before proceeding"

# help: gen-upgrade-sets <--opts> [previous perl version] [wanted perl version]
# help:
# help: example:
# help:   gen-upgrade-sets 5.22 5.24
# help:
# help: In both cases, the version should be the "subslot" value used by portage
# help: which will be likely 5.22, 5.24, 5.26, etc. ( But unlikely 5.22.1, 5.22.2 etc )
# help:
# help: This will generate two sets:
# help:
# help:   @perl-cleanup - Contains packages we encourage removal of before upgrading
# help:   @perl-upgrade - Contains packages that will need rebuilding during upgrade
# help:
# help: If an upgrade fails mid-way, regenerating these sets will regenerate the
# help: sets with fewer upgrades to install, which is probably what you want.
# help:
# help: OPTIONS:
# help:   --quiet         - Suppresses all info/warnings except for fatal ones.
# help:
# help:   --suffix=[name] - Append a user specified suffix string onto generated set
# help:   --suffix [name]   names.
# help:
# help: ENVIRONMENT
# help:   By default, this tool writes to /etc/portage/sets, and the following variables
# help:   can be employed in your environement to allow writing to a different location
# help:
# help:   ETC_PORTAGE
# help:     Defaults to /etc/portage
# help:
# help:   ETC_PORTAGE_SETS
# help:     Defaults to ${ETC_PORTAGE}/sets
