#!/bin/bash
set +o posix
shopt -s extglob

#
# Script : slackwarearm-current/source/x/x11/x11-vermgr.sudhelper
# Purpose: Handle the package version & build numbers automatically
#          for the X11 modular packages present within Slackware x86/64.
#
#          This is a helper script for the ''Sud'' Slackware ARM build system.
#
# by Stuart Winter <mozes@slackware.com>
#
# Copyright 2021  Stuart Winter, Surrey, England.
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Build numbers
# -------------
# You can set specific build numbers by creating the
# package name inside build-nums dir:
# echo 2 > build-nums/xinit
#

source /usr/share/slackdev/buildkit.sh

display_help() {
cat << EOF
 -u,  --update       Run in Update mode [ this is the default ]
 -r,  --remove       Run in Remove mode
                     This handles the removal of any X11 modular
                     packages tagged as 'Removed'.
                     This is for when Sud runs with the -r flag
                     [ default: off ]
                     -r disables -u

 -c,  --changelog    Override the default location of the Slackware
                     ChangeLog.txt [ default: $CHANGELOG ]
EOF
}

# Return a package name that has been stripped of the dirname portion
# and any of the valid extensions (only):
pkgbase() {
  # basename + strip extensions .tbz, .tgz, .tlz and .txz
  echo "$1" | sed 's?.*/??;s/\.t[bglx]z$//'
}

# Strip version, architecture and build from the end of the name
package_name() {
  pkgbase $1 | sed 's?-[^-]*-[^-]*-[^-]*$??'
}


# Handle versions and build numbers for the Slackware upstream packages
# i.e. those that appear in Slackware x86/64.
function handleversion () {

 local PKGNAME=$1
 local X86_PKG_FILE_NAME X86_PKG_FILE_VERSION X86_PKG_FILE_BUILDNUM

  # Obtain package information for the x86 package:
  if [ "${PATCHES}" = "yes" ]; then
     # On stable builders, SLACKSOURCE is set to slackware-xx/patches/source within /usr/share/slackdev/slackdev.config
     pushd $SLACKSOURCE/../packages/ > /dev/null 2>&1
     X86_PKG_FILE_NAME=$( pkgbase ${PKGNAME}-+([^-])-+([^-])-+([^-]).t?z )
     X86_PKG_FILE_VERSION=$( pkgbase ${PKGNAME}-+([^-])-+([^-])-+([^-]).t?z | rev | cut -d- -f3 | rev )
     X86_PKG_FILE_BUILDNUM=$( pkgbase ${PKGNAME}-+([^-])-+([^-])-+([^-]).t?z | rev | cut -d- -f1 | rev )
     popd > /dev/null 2>&1
   else
     pushd $SLACKSOURCE/../slackware*/x > /dev/null 2>&1
     X86_PKG_FILE_NAME=$( pkgbase ${PKGNAME}-+([^-])-+([^-])-+([^-]).t?z )
     X86_PKG_FILE_VERSION=$( pkgbase ${PKGNAME}-+([^-])-+([^-])-+([^-]).t?z | rev | cut -d- -f3 | rev )
     X86_PKG_FILE_BUILDNUM=$( pkgbase ${PKGNAME}-+([^-])-+([^-])-+([^-]).t?z | rev | cut -d- -f1 | rev )
     popd > /dev/null 2>&1
  fi

   echo "X11 modular package: $PKGNAME"
   echo "--------------------"
   printf "\tUpstream details :\n"
   printf "\tPackage file name: $X86_PKG_FILE_NAME\n"
   printf "\tPackage version..: $X86_PKG_FILE_VERSION\n"
   printf "\tPackage Build....: $X86_PKG_FILE_BUILDNUM\n"
   echo

   # Sanity check the x86 values:
   if [ ! -z "$X86_PKG_FILE_NAME" -a ! -z "$X86_PKG_FILE_VERSION" -a ! -z "$X86_PKG_FILE_BUILDNUM" ]; then
      # Obtain existing ARM versions.
      # We store the existing/previous version within the ARM build number files.
      if [ -s $PORTSRC/source/x/x11/build-nums/upstreampkgs/$PKGNAME ]; then
         source $PORTSRC/source/x/x11/build-nums/upstreampkgs/$PKGNAME
       else
         # May be 'Added' in this batch - no matter, we'll create it.
         printf "\tNo existing ARM port build details found (will create new)\n"
      fi
      # MODBUILD and _PKGVER are (possibly) set within the ARM build number file.
      # However, _PKGVER isn't always present (or wasn't using the previous build system, anyway!)
      # Sanity check them:
      [ -z "${MODBUILD}" ] && MODBUILD=Unset
      [ -z "${_PKGVER}" ] && _PKGVER=Unset
      printf "\tARM port details :\n"
      printf "\tPackage version..: $_PKGVER "
      # Firstly, if the version number doesn't match, let's take the one
      # upstream and set it for ARM.
      # This way we handle Added packages *and* Upgrades/Downgrades.
      if [ "${_PKGVER}" != "${X86_PKG_FILE_VERSION}" ]; then
         #printf " Out of sync - changing to match upstream, build=1\n"
         printf " -> $X86_PKG_FILE_VERSION\n"
         printf "\tBuild number.....: $MODBUILD -> 1\n"
         echo "_PKGVER=${X86_PKG_FILE_VERSION}" > $PORTSRC/source/x/x11/build-nums/upstreampkgs/$PKGNAME
         echo "MODBUILD=1" >> $PORTSRC/source/x/x11/build-nums/upstreampkgs/$PKGNAME
       else
         # It must be a rebuild, so let's bump it!
         #printf "Version check: In sync - incrementing build number\n"
         printf " = $X86_PKG_FILE_VERSION [ in sync ]\n"
         printf "\tBuild number.....: $MODBUILD -> "
         let MODBUILD++
         printf " $MODBUILD\n"
         echo "_PKGVER=${_PKGVER}" > $PORTSRC/source/x/x11/build-nums/upstreampkgs/$PKGNAME
         echo "MODBUILD=$MODBUILD" >> $PORTSRC/source/x/x11/build-nums/upstreampkgs/$PKGNAME
      fi
    else
      # The x86 file/ver/build is missing:
      printf "\tERROR: Unable to detect upstream package file details for package: $PKGNAME\n"
   fi
#   echo "ARM's build setting:"
#   cat $PORTSRC/source/x/x11/build-nums/upstreampkgs/$PKGNAME

}

# Location of Slackware Change Log.  Since this is an r2b helper script, it's normally
# called with the change log file path explicitly defined using the '-c' operator
# to this script.
CHANGELOG=$PORTSRC/ChangeLog.txt
# Default actions:
UPDATEMODE=Yes
REMOVEMODE=No

# Temporary package list:
SUD_PKGLIST=/tmp/sud-x11list
rm -f $SUD_PKGLIST

# Get script parameters:
PARAMS="$( getopt -qn "$( basename $0 )" -o urc: -l update,remove,changelog: -- "$@" )"
# If params are incorrect then
if [ $? -gt 0 ]; then display_help >&2 ; exit 2 ; fi
eval set -- "${PARAMS}"
for param in $* ; do
  case "$param" in

     -u|--update)    UPDATEMODE=Yes
                     REMOVEMODE=No
                     shift ;;

     -r|--remove)    REMOVEMODE=Yes
                     UPDATEMODE=No
                     shift ;;

     -c|--changelog) CHANGELOG="$2"
                     shift 2;;

     --) shift; break;;
  esac
done

echo "Sud helper for X11"
echo "Slackware Change Log (acting as a build list): $CHANGELOG"

# Sanity checks:
# Ensure that the SUD markers are present, as that indicates Sud has been run
# and that we've had a manual check through the list.
if [ "$( grep -E '^\**SUD|^\**SUD' ${CHANGELOG} | xargs )" != "**SUD **SUD" ]; then
   printf "\nERROR: r2b markers are not present within ${CHANGELOG}, or perhaps less than or more than one set?\n"
   exit 1
fi

# If building in /patches for a Stable Release, we drop the packages into /tmp/patches/
slack_findpkgstore_is_stablerelease && { PATCHES=yes ;} || { PATCHES=no ;}

# If running in update mode:
if [ "$UPDATEMODE" = "Yes" ]; then
   # Find packages between the R2B markers, filtering out any 'Removed' packages
   # (as these are handled by 'Sud'), and handle the version and build details:
   while read line ; do
      pkg=$( package_name $( echo $line | awk -F: '{print $1}' ) )

       # Is it excluded for ARM?
       if [ -z "$( grep -E "^${pkg}$" $PORTSRC/source/x/EXCLUDED_PKGS )" ]; then
          # Ensure it's one of the X11 modular packages, not one of the others
          # that is a separate package within the 'x' series:
          if [ -d $SLACKSOURCE/x/$pkg ]; then
             # It's in Slackware's X series but not part of X.org:
             echo "WARNING: $pkg is not an X11 modular package - ignored (will be handled by Sud directly)"
           else
             # It's part of X.org - one of the modular packages.
             # Add it to the list of Upgraded/Rebuilt/Added packages:
             echo $pkg >> $SUD_PKGLIST
          fi
        else
           echo "WARNING: x/${pkg} is excluded on Slackware ARM"
       fi
       # This script is expected to be run from Sud, after it prefixes the '_X11MOD_' token
       # to the modular X11 package.
       # If you want to run this against a non-Sud'd list, remove the first grep -E below.
   done< <( sed -n '/^**SUD/,/^**SUD/p' $CHANGELOG | grep -E "^_X11MOD_" | sed -e 's?_X11MOD_ ??g' -e 's?^+??g' | grep -E "^x/.*t[bglx]z:" | grep -v ":[[:space:]]\{2,\}Removed\.$" | cut -d/ -f2 )

   # Remove any duplicates from the list, and process it:
   while read pkg ; do
      handleversion $pkg
   done< <( sort -u $SUD_PKGLIST )

 elif [ "$REMOVEMODE" = "Yes" ]; then
   # Handle any 'Removed' packages that are part of core KDE
   # (don't have their own package dir within the kde/ dir).
#
# NOTE: UNTESTED!!
# NOTE: UNTESTED!!
# NOTE: UNTESTED!!
# NOTE: UNTESTED!!
   # Needs to support:
   #  * Removal from both ARM and aarch64 ports - the txz packages#
   #  * Backup & removal of the non-core KDE packages - source/kde/<pkgname>

   echo "*** Removal mode not implemented yet. Code it up next time around!"
#   return 1
fi

