#!/bin/bash

ME=${0##*/}

usage() {

    cat <<Usage

Usage:  $ME [<file>|options]

Update the Unattended-Upgrade::Origins-Pattern for most currently enabled
repos with the exceptions of the Debian Backports and Debian Experimental
repos.

File:

    File to be updated. Typically this would be the /etc/apt/apt.conf.d/
    51unattended-upgrades-mx file but can be any file user has read/write
    permissions to.

    If no file argument provided, output will be written to stdout.

Options:

    -d, --default
        Default to updating the Origins-Pattern in the
        /etc/apt/apt.conf.d/51unattended-upgrades-mx file.

    -h, --help
        Show this help.
Usage
}

main() {

	if [ $# -gt 1 ]; then
          echo "$ME":' too many option(s) or file argument(s) -- '"$@"
	  echo 'Try '"$ME"' --help for more information.' 
	  exit 1
	fi

	if [ "$1" = "-h" -o "$1" = "--help" ]; then
	  usage
	  exit 0
	fi

        bad_option="true"

        if [ "$1" = "-d" -o "$1" = "--default" ]; then
          bad_option="false"
        fi

        if [ "$(cut -c1 <<<"$1")" = "-" ] && [ "$bad_option" = "true" ]; then
	  echo "$ME":' invalid option(s) -- '"$@"
	  echo 'Try '"$ME"' --help for more information.' 
	  exit 1
	fi

	if [ ! -f "$1" ] && [ $# -ge 1 ] && [ "$bad_option" = "true" ]; then
          echo "$ME":' passed argument is not a valid file  -- '"$@"
	  echo 'Try '"$ME"' --help for more information.' 
	  exit 1
	fi


	local File Start End Cache_Origins Cache_Org_md5 Exist_Origins Existing__md5

    #Attempt to remove file causing apt-cache policy syntax error (if there is one)
    #note, this won't work for non-root users.
    apt-cache policy 2>&1 | grep 'E: Syntax error' 1>/dev/null 2>/dev/null && [ $? ] && \
    rm -f "$(apt-cache policy 2>&1 | grep 'E: Syntax error' | cut -f4 -d\ | cut -f1 -d:)"

    if [ $# -eq 0 ]
      then
        File=""
        Start="Unattended-Upgrade::Origins-Pattern {"
        End="};"
      else
        if [ "$1" = "-d" ] || [ "$1" = "--default" ]
          then
            File="/etc/apt/apt.conf.d/51unattended-upgrades-mx"
          else
            File="$1"
        fi
        if [ -f "$File" ]
          then
            Start="$(grep 'Unattended-Upgrade::Origins-Pattern {' -B9999 "$File")"
            End="$(grep '};' -A9999 "$File")"
          else
            cp /usr/share/apt-notifier/51unattended-upgrades-mx  "$File"
            sed -i '$d' "$File"
            Start="$(grep 'Unattended-Upgrade::Origins-Pattern {' -B9999 "$File")"
            End="$(grep '};' -A9999 "$File")"
        fi
    fi
   #Create a Origins-Pattern for all currently enabled repos
    Cache__policy="$(apt-cache policy                                                               )"
    Cache_Origins="$(cat                                                         <<<"$Cache__policy")"
    Cache_Origins="$(grep -v Translation-[a-z]{2}$ -E                            <<<"$Cache_Origins")"
    Cache_Origins="$(grep -v 'Pinned packages:'                                  <<<"$Cache_Origins")"
    Cache_Origins="$(grep ^\ [0-9]+ -A1 -E                                       <<<"$Cache_Origins")"
    Cache_Origins="$(grep -v -e--                                                <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/,\([abclno][=]\)/@\1/g'                              <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/,/\\,/g'                                             <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/@/,/g'                                               <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/^[ ]* //g'                                           <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/^\([0-9]\)/\/\/  \1/'                                <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/^\/\//\/\/\n\/\//'                                   <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/^release //'                                         <<<"$Cache_Origins")"
   #Cache_Origins="$(sed 's/v=[0-9.a-zA-Z]*,//'                                  <<<"$Cache_Origins")"
   #Cache_Origins="$(sed 's/,b=amd64//'                                          <<<"$Cache_Origins")"
   #Cache_Origins="$(sed 's/,b=i386//'                                           <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/,/\n/g'                                              <<<"$Cache_Origins")"
    Cache_Origins="$(sed '/[bv]=.*/d'                                            <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/^\([aclno]\)/,\1/'                                   <<<"$Cache_Origins")"
    Cache_Origins="$(sed ':a;N;$!ba;s/\n//g'                                     <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/Packages,/\n/g'                                      <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/status,/status\n/g'                                  <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's,////,//\n//,g'                                       <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's,//$,\n//,g'                                          <<<"$Cache_Origins")"
    Cache_Origins="$(sed '/^$/d'                                                 <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/^\([aclno]=.*\)/   "\1";/'                           <<<"$Cache_Origins")"

   #Now Disable Unattended Upgrades for Debian Backports & Experimental repos
   #Cache_Origins="$(sed 's/^\([ ]*.*Debian Backports\)/\/\/\1/'                 <<<"$Cache_Origins")"
   #Cache_Origins="$(sed 's/^\([ ]*.*Debian Experimental\)/\/\/\1/'              <<<"$Cache_Origins")"
   #Cache_Origins="$(sed 's/\/\/    "/\/\/  "/'                                  <<<"$Cache_Origins")"

   #As an alternative, disable Unattended Upgrades for Pin-Prioritys less than 500, the 
   #Debian Backports & Experimental repos will also be disabled by this.
    Cache_Origins="$(sed  '/^\/\/  [0-4][0-9]*[0-9]* /a @@'                      <<<"$Cache_Origins")"
	Cache_Origins="$(sed '/@@/N;y/\n/\t/'                                        <<<"$Cache_Origins")"
    Cache_Origins="$(sed 's/\t  //'                                              <<<"$Cache_Origins")"
	Cache_Origins="$(sed 's/@@/\/\//'                                            <<<"$Cache_Origins")"

   #Disable Unattended Upgrades from MX testrepos
	Cache_Origins="$(sed 's/^   \(.*l=MX repository,c=test.*\)/\/\/ \1/'         <<<"$Cache_Origins")"

   #Disable Unattended Upgrades from Debian Multimedia repos
	Cache_Origins="$(sed 's/^   \(.*Unofficial Multimedia Packages.*\)/\/\/ \1/' <<<"$Cache_Origins")"
    
   #Disable Unattended Upgrades from Debian testing, currently known as "buster"
    Cache_Origins="$(sed 's/^   \(.*o=Debian,a=testing.*\)/\/\/ \1/'             <<<"$Cache_Origins")"

   #Disable Unattended Upgrades from Debian sid or unstable
    Cache_Origins="$(sed 's/^   \(.*o=Debian,a=unstable.*\)/\/\/ \1/'            <<<"$Cache_Origins")"

   #Disable Debian releases other than the one that this MX is based upon
    Debian_allowd="$(grep -v  Translation-[a-z]{2}$ -E                           <<<"$Cache__policy")" 
    Debian_allowd="$(grep ^'     release v=[0-9.]+,o=Debian' -E                  <<<"$Debian_allowd")" 
    Debian_allowd="$(grep v=$(cut -f1 -d. /etc/debian_version)                   <<<"$Debian_allowd")"
    Debian_allowd="$(grep o=Debian,a=.*,n=.*, -Eo -m1                            <<<"$Debian_allowd")"
    Debian_allowd="$(cut -f1-3 -d\,                                              <<<"$Debian_allowd")"
    for i in $(\
    grep -v Translation-[a-z]{2}$ -E <<<"$Cache__policy" |\
    grep ^'     release v=[0-9.]+,o=Debian' -E |\
    grep -v "$Debian_allowd" |\
    grep o=Debian,a=.*,n=.*, -Eo |\
    cut -f1-3 -d\, |\
    sort -u \
    ); \
    do \
    Cache_Origins="$(sed 's/   \(.*'"$i"'.*\)/\/\/ \1/'                          <<<"$Cache_Origins")";\
    done

   #Get a sum of the apt-cache Origins-Pattern 
    Cache_Org_md5="$(md5sum                                                      <<<"$Cache_Origins")"
    Cache_Org_md5="$(awk    '{print $1}'                                         <<<"$Cache_Org_md5")"

   #Get a sum of the existing Origins-Pattern 
    Exist_Origins="$(grep '};' -B9999 -m1 "$File" 2>/dev/null                                       )"
    Exist_Origins="$(head -n -1                                                  <<<"$Exist_Origins")"
    Exist_Origins="$(tail -n +2                                                  <<<"$Exist_Origins")"
    Existing__md5="$(md5sum                                                      <<<"$Exist_Origins")"
    Existing__md5="$(awk '{print $1}'                                            <<<"$Existing__md5")"

   #Compare the pattern sums, update the Unattended-Upgrade::Origins-Pattern if it has
   #changed since last checked.
    if [ "$Cache_Org_md5" != "$Existing__md5" ]
      then
        if [ -n "$File" ]
          then
            cat <<<"$Start"          > "$File"
            cat <<<"$Cache_Origins" >> "$File"
            cat <<<"$End"           >> "$File"
            #If now getting a syntax error when running the apt-cache policy command,
            #assume that the new Origins-Pattern that was just created is causing it,
            #set the Origins-Pattern back to a empty pattern.    
            apt-cache policy 2>&1 | grep 'E: Syntax error' -q && if [ $? ]; then \
            cp /usr/share/apt-notifier/51unattended-upgrades-mx "$File"; sed -i '$d' "$File"; fi
          else
            cat <<<"$Start"
            cat <<<"$Cache_Origins"
            cat <<<"$End"
        fi
      else
       :
    fi
}

main "$@"

exit 0
