#! /bin/sh

# deb-mix v1.0
# Track which Debian suite currently installed packages come from
# Copyright (c) 2016 Raphaël Halimi <raphael.halimi@gmail.com>

# Source shell-script-helper
. /lib/shell-script-helper


#
# Variables
#

# Configuration files
SYSTEM_CONFIG_FILE="/etc/$(basename "$0").conf"
USER_CONFIG_FILE="$HOME/.$(basename "$0").conf"

# Options defaults
MAX_LIST=5
SCALE=2


#
# Functions
#

print_usage () {
  printf "Usage: %s [OPTION]...\n" "$(basename "$0")"
  printf "Track which Debian suite currently installed packages come from\n"
  printf "\nOPTIONS:\n"
  print_option "-m MAX_LIST" "Maximum number of packages to show, default is 5"
  print_option "-s SCALE" "Digits after the decimal point, default is 2"
  print_option "-v" "Verbose mode"
  print_option "-d" "Debug mode"
  print_option "-h" "Print this help message"
}

how_many () {
  PATTERN="$1"
  PRETTY_TEXT="$2"
  print_debug "PATTERN=$PATTERN" "PRETTY_TEXT=$PRETTY_TEXT"
  PKG_COUNT=$(printf "%s\n" "$PKG_LIST" | grep -c "$PATTERN")

  # If packages are found, print some info
  if [ "$PKG_COUNT" -ne 0 ] ; then
    printf "%i %s (%g %%)" "$PKG_COUNT" "$PRETTY_TEXT" "$(printf "scale=%i; %i*100/%i\n" "$SCALE" "$PKG_COUNT" "$TOTAL_PKG" | bc -q)"

    # If there are less than MAX_LIST, print their names
    if [ "$PKG_COUNT" -le "$MAX_LIST" ] ; then
      printf ": %s\n" "$(printf "%s" "$PKG_LIST" | grep "$PATTERN" | awk '{print $1}' | cut -d "/" -f 1 | cut -d ":" -f 1 | xargs)"
    else
      printf "\n"
    fi

    # If pattern starts with / (e.g. is a release name), check for variants
    if printf "%s" "$PATTERN" | grep -q ^/ ; then
      for VARIANT in security updates proposed proposed-updates backports ; do
        print_debug "VARIANT=$VARIANT"
        PKG_COUNT="$(printf "%s\n" "$PKG_LIST" | grep -c "${PATTERN}-${VARIANT}$")"

        # If packages are found, print some info
        if [ "$PKG_COUNT" -ne 0 ] ; then
          printf "  including %i %s (%g %%)" "$PKG_COUNT" "$VARIANT" "$(printf "scale=%i; %i*100/%i\n" "$SCALE" "$PKG_COUNT" "$TOTAL_PKG" | bc -q)"
          if [ "$PKG_COUNT" -le "$MAX_LIST" ] ; then
            printf ": %s\n" "$(printf "%s" "$PKG_LIST" | grep "$PATTERN-$VARIANT" | awk '{print $1}' | cut -d "/" -f 1 | cut -d ":" -f 1 | xargs)"
          else
            printf "\n"
          fi
        fi
      done
    fi
  fi
}


#
# Config files
#

[ -e "$SYSTEM_CONFIG_FILE" ] && . "$SYSTEM_CONFIG_FILE"
[ -e "$USER_CONFIG_FILE" ] && . "$USER_CONFIG_FILE"


#
# Options processing
#

while getopts "m:s:vdh" OPTION ; do
  case $OPTION in
    m) MAX_LIST="$OPTARG" ;;
    s) SCALE="$OPTARG" ;;
    v) enable_verbose ;;
    d) enable_debug ;;
    h) print_usage ; exit 0 ;;
    *) print_usage ; exit 1 ;;
  esac
done ; shift $((OPTIND-1))
print_debug "MAX_LIST=$MAX_LIST" "SCALE=$SCALE"


#
# Checks
#

# This script needs bc, apt-show-versions
for BINARY in bc apt-show-versions ; do
  which "$BINARY" > /dev/null || die "Please install $BINARY"
done


#
# MAIN
#

# Our main data source - all installed packages
print_verbose "Building package list"
PKG_LIST=$(apt-show-versions -b | grep -v 'not installed$')

# Total packages
TOTAL_PKG=$(printf "%s\n" "$PKG_LIST" | wc -l)
print_debug "TOTAL_PKG=$TOTAL_PKG"
printf "%i packages currently installed\n" "$TOTAL_PKG"

# List all releases installed, excluding variants
RELEASE_LIST="$(printf "%s\n" "$PKG_LIST" | grep / | cut -d / -f 2 | cut -d "-" -f 1 | sort -u | xargs)"
print_debug "RELEASE_LIST=$RELEASE_LIST"

# Count packages from releases
for RELEASE in $RELEASE_LIST ; do
  case $RELEASE in

    # Debian GNU/Linux codenames
    hamm) how_many "/$RELEASE" "from Debian 2 Hamm" ;;
    slink) how_many "/$RELEASE" "from Debian 2.1 Slink" ;;
    potato) how_many "/$RELEASE" "from Debian 2.2 Potato" ;;
    woody) how_many "/$RELEASE" "from Debian 3 Woody" ;;
    sarge) how_many "/$RELEASE" "from Debian 3.1 Sarge" ;;
    etch) how_many "/$RELEASE" "from Debian 4 Etch" ;;
    lenny) how_many "/$RELEASE" "from Debian 5 Lenny" ;;
    squeeze) how_many "/$RELEASE" "from Debian 6 Squeeze" ;;
    wheezy) how_many "/$RELEASE" "from Debian 7 Wheezy" ;;
    jessie) how_many "/$RELEASE" "from Debian 8 Jessie" ;;
    stretch) how_many "/$RELEASE" "from Debian 9 Stretch" ;;
    sid) how_many "/$RELEASE" "from Debian Sid" ;;

    # Debian GNU/Linux suites
    oldoldstable) how_many "/$RELEASE" "from Debian Old Old Stable" ;;
    oldstable) how_many "/$RELEASE" "from Debian Old Stable" ;;
    stable) how_many "/$RELEASE" "from Debian Stable" ;;
    testing) how_many "/$RELEASE" "from Debian Testing" ;;
    unstable) how_many "/$RELEASE" "from Debian Unstable" ;;
    experimental) how_many "/$RELEASE" "from Debian Experimental" ;;

    # Ubuntu Linux
    warty) how_many "/$RELEASE" "from Ubuntu 4.10 Warty Warthog" ;;
    hoary) how_many "/$RELEASE" "from Ubuntu 5.04 Hoary Hedgehog" ;;
    breezy) how_many "/$RELEASE" "from Ubuntu 5.10 Breezy Badger" ;;
    dapper) how_many "/$RELEASE" "from Ubuntu 6.06 LTS Dapper Drake" ;;
    edgy) how_many "/$RELEASE" "from Ubuntu 6.10 Edgy Eft" ;;
    feisty) how_many "/$RELEASE" "from Ubuntu 7.04 Feisty Fawn" ;;
    gutsy) how_many "/$RELEASE" "from Ubuntu 7.10 Gutsy Gibbon" ;;
    hardy) how_many "/$RELEASE" "from Ubuntu 8.04 LTS Hardy Heron" ;;
    intrepid) how_many "/$RELEASE" "from Ubuntu 8.10 Intrepid Ibex" ;;
    jaunty) how_many "/$RELEASE" "from Ubuntu 9.04 Jaunty Jackalope" ;;
    karmic) how_many "/$RELEASE" "from Ubuntu 9.10 Karmic Koala" ;;
    lucid) how_many "/$RELEASE" "from Ubuntu 10.04 LTS Lucid Lynx" ;;
    maverick) how_many "/$RELEASE" "from Ubuntu 10.10 Maverick Meerkat" ;;
    natty) how_many "/$RELEASE" "from Ubuntu 11.04 Natty Narwhal" ;;
    oneiric) how_many "/$RELEASE" "from Ubuntu 11.10 Oneiric Ocelot" ;;
    precise) how_many "/$RELEASE" "from Ubuntu 12.04 LTS Precise Pangolin" ;;
    quantal) how_many "/$RELEASE" "from Ubuntu 12.10 Quantal Quetzal" ;;
    raring) how_many "/$RELEASE" "from Ubuntu 13.04 Raring Ringtail" ;;
    saucy) how_many "/$RELEASE" "from Ubuntu 13.10 Saucy Salamander" ;;
    trusty) how_many "/$RELEASE" "from Ubuntu 14.04 LTS Trusty Tahr" ;;
    utopic) how_many "/$RELEASE" "from Ubuntu 14.10 Utopic Unicorn" ;;
    vivid) how_many "/$RELEASE" "from Ubuntu 15.04 Vivid Vervet" ;;
    wily) how_many "/$RELEASE" "from Ubuntu 15.10 Wily Werewolf" ;;
    xenial) how_many "/$RELEASE" "from Ubuntu 16.04 LTS Xenial Xerus" ;;

    # Linux Mint
    debian) how_many "/$RELEASE" "from Linux Mint Debian Edition" ;;
    ada) how_many "/$RELEASE" "from Linux Mint 1 Ada" ;;
    barbara) how_many "/$RELEASE" "from Linux Mint 2 Barbara" ;;
    bea) how_many "/$RELEASE" "from Linux Mint 2.1 Bea" ;;
    bianca) how_many "/$RELEASE" "from Linux Mint 2.2 Bianca" ;;
    cassandra) how_many "/$RELEASE" "from Linux Mint 3 Cassandra" ;;
    celena) how_many "/$RELEASE" "from Linux Mint 3.1 Celena" ;;
    daryna) how_many "/$RELEASE" "from Linux Mint 4 Daryna" ;;
    elyssa) how_many "/$RELEASE" "from Linux Mint 5 Elyssa" ;;
    felicia) how_many "/$RELEASE" "from Linux Mint 6 Felicia" ;;
    gloria) how_many "/$RELEASE" "from Linux Mint 7 Gloria" ;;
    helena) how_many "/$RELEASE" "from Linux Mint 8 Helena" ;;
    isadora) how_many "/$RELEASE" "from Linux Mint 9 Isadora" ;;
    julia) how_many "/$RELEASE" "from Linux Mint 10 Julia" ;;
    katya) how_many "/$RELEASE" "from Linux Mint 11 Katya" ;;
    lisa) how_many "/$RELEASE" "from Linux Mint 12 Lisa" ;;
    maya) how_many "/$RELEASE" "from Linux Mint 13 LTS Maya" ;;
    nadia) how_many "/$RELEASE" "from Linux Mint 14 Nadia" ;;
    olivia) how_many "/$RELEASE" "from Linux Mint 15 Olivia" ;;
    petra) how_many "/$RELEASE" "from Linux Mint 16 Petra" ;;
    qiana) how_many "/$RELEASE" "from Linux Mint 17 LTS Qiana" ;;
    rebecca) how_many "/$RELEASE" "from Linux Mint 17.1 LTS Rebecca" ;;
    rafaela) how_many "/$RELEASE" "from Linux Mint 17.2 LTS Rafaela" ;;
    rosa) how_many "/$RELEASE" "from Linux Mint 17.3 LTS Rosa" ;;
    sarah) how_many "/$RELEASE" "from Linux Mint 18 LTS Sarah" ;;

  esac
done

# Count other packages
how_many "newer than version in archive" "newer than version in archive"
how_many "No available version" "with no available version"
how_many "unknown" "from unknown source"
