#!/usr/sbin/env bash

usage() {
  echo "usage: ${0##*/} [options]"
  echo " -g git-branch  Use an alternate git branch for iso-profiles to test"
  echo " -v             Print verbose information"
  echo " -m             Mail the maintainers of broken profiles"
  echo " -b branch      Select the pacman branch to test with"
  echo " -r             Remove profiles that don't pass the test"
  echo " -h             Print this help message"
  echo ''
  echo ' profile-validate test the current iso-profiles to ensure that they work with manjaro-architect.'
  echo ' If no git branch is given, it defaults to the master branch.'
  echo ''
  echo ''
  exit $1
}

verbose=false
mail=false
bswitch=false
pkgs_target=/tmp/package_list
PROFILES="/tmp/profiles"
branch=master
filter=false
while getopts ":g:b:vmrh" opt; do
  case $opt in
    g)
      echo "Using the git branch: $OPTARG" >&2
      branch=$OPTARG
      bswitch=1
      ;;
    v)
      verbose=true
      ;;
    m)
      mail=true
      ;;
    b)
      echo "Using the git branch: $OPTARG" >&2
      pbranch=$OPTARG
      ;;
    r)
      filter=true
      ;;
    h)
      usage
      exit 0
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      usage
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires git branch as an argument." >&2
      usage
      exit 1
      ;;
  esac
done

sendmail() {
  printf '%s\n' \
  "Failed iso-profiles:" \
  "$(cat /tmp/failed_profiles | sort | uniq)"  | mail -s "Iso-profile broken"  "manjaro-dev@manjaro.org"
}

filter_packages() {
  # Parse package list based on user input and remove parts that don't belong to pacman
  cat "$pkgs_src" > $pkgs_target
  # Remove any packages tagged with >i686 and remove >x86_64 tags
  sed -i '/>i686/d' $pkgs_target
  sed -i '/>nonfree_i686/d' $pkgs_target
  sed -i 's/>x86_64 //g' $pkgs_target

  # Remove >multilib tags
  sed -i 's/>multilib //g' $pkgs_target
  sed -i 's/>nonfree_multilib //g' $pkgs_target

  sed -i 's/>extra //g' $pkgs_target
  sed -i '/>basic/d' $pkgs_target

  # Remove commented lines
  # remove everything except the first word of every lines
  sed -i 's/\s.*$//' $pkgs_target
  # Remove lines with #
  sed -i '/#/d' $pkgs_target
  # remove KERNEL variable
  sed -i '/KERNEL/d' $pkgs_target
  # Remove empty lines
  sed -i '/^\s*$/d' $pkgs_target
}

test_profile() {
  pkgs_src="$(echo $PROFILES/*/$profile/Packages-Desktop)"
  filter_packages
  $verbose && echo "Testing profile $profile"
  comm -23 <(sort -u "$pkgs_target") <(grep -v -e ”\" -e "\/" -e "\:" -e "pkgname" /tmp/.available_packages | sort -u) > /tmp/fails-$profile
  if [[ "$(cat /tmp/fails-$profile | wc -l)" -gt 0 ]]; then
    if $filter; then
      rm -rf $(echo $PROFILES/*/$profile)
    else
      echo -e "Profile \e[31m$profile\e[0m did not pass the test."
      echo -e "The offending packages are:"
      echo -e "\e[31m$(cat /tmp/fails-$profile)\e[0m\n"
      echo "$profile" >> /tmp/failed_profiles
      source $(echo $PROFILES/*/$profile/profile.conf)
    fi
  else
    rm /tmp/fails-$profile
    $verbose && echo -e "Profile \e[36m$profile\e[0m passed the test\n"
  fi  
}

loop_profiles() {
  if $filter; then
    profile_list="$(echo $PROFILES/{manjaro,community}/* | tr " " "\n" | cut -f7 -d'/' | grep -vE "netinstall|architect|grub")"
  else
    profile_list="$(echo $PROFILES/{manjaro,community}/* | tr " " "\n" | cut -f5 -d'/' | grep -vE "netinstall|architect|grub")"
  fi
  for profile in $profile_list; do
    test_profile
  done
}

setup_profiles() {
  if [[ -e $PROFILES ]]; then
    if $verbose; then
      echo "updating isoprofiles"
      git -C $PROFILES pull
    else
      git -C $PROFILES pull &> /dev/null
    fi
  else
    if $verbose; then
      echo "pulling isoprofiles"
      git clone -b $branch --depth 1 https://gitlab.manjaro.org/profiles-and-settings/iso-profiles.git $PROFILES
      echo -e "\n"
    else
      git clone -q -b $branch --depth 1 https://gitlab.manjaro.org/profiles-and-settings/iso-profiles.git $PROFILES
    fi
  fi
}

list_available_pgs() {
  cat <(pacman -Ssq) <(pacman -Sgq) <(expac "%S" -Ss | tr " " "\n") | sort | uniq > /tmp/.available_packages    
}

main() {
  list_available_pgs 
  if $filter; then
    PROFILES='/usr/share/manjaro-architect/profiles'
  fi
  setup_profiles
  loop_profiles
  if ! $filter && [[ "$(cat /tmp/failed_profiles 2> /dev/null | wc -l 2> /dev/null)" -gt 0 ]]; then
    echo "--------------"
    echo "Following profiles failed the test:"
    echo -e "\e[31m$(cat /tmp/failed_profiles | sort | uniq)\e[0m" 
    $mail && sendmail
    rm /tmp/failed_profiles
    exit 1
  fi
  [[ -e "/tmp/failed_profiles" ]] && rm /tmp/failed_profiles || true
}

if $bswitch; then
  rm -rf $PROFILES
fi

main 
