#!/bin/sh

usage="$0 <sourcelist>"

verbose=0

if [ $# -lt 1 ]; then
  echo $usage
  exit 1
fi

srclist=$1
shift

if [ ! -f $srclist ]; then
  echo "$srclist doesn't exist or is not a regular file"
fi

aptopts="-o Dir::State::status=/dev/null -o Dir::Cache=./apt/cache -o Dir::Etc::SourceList=$srclist -o Dir::State=./apt/state -o Debug::NoLocking=1"

if [ -e apt ]; then
  echo "./apt already exists - remove it & re-execute to continue"
  exit 1
fi

mkdir -p apt/state/lists/partial apt/cache/archives/partial

apt-get $aptopts update 1>&2 # don't add noise to stdout

## Spits out a list of installed packages
## Doesn't take into account packages in a bad state
list_installed() {
  COLUMNS=500 dpkg -l | grep ^ii | awk '{ print $2,$3 }'
}

## A two letter key is used to make output easily greppable.
(echo === Key ===
 echo "SU - This package is supported and no outstanding updates are available"
 echo "SA - This package is supported and an update is available"
 echo "NA - This version is not supported, but a supported version is available"
 echo "NN - This package is not supported; no supported version is available"
 echo === Key ===
) 1>&2

list_installed | while read p; do
  name=$(echo $p | cut -d ' ' -f 1)
  ver=$(echo $p | cut -d ' ' -f 2)

  ## this sed drops epochs, because dpkg -l drops them
  avail=$(apt-cache $aptopts show $name 2> /dev/null | \
          grep ^Version: | cut -d ' ' -f 2 | sed 's/.*\://') 
  if [ -z "$avail" ]; then
    echo NA: $name \($ver\)
    continue
  else
    gavail=""
    for v in $avail; do
      if [ -z $gavail ]; then
        gavail=$v
      elif dpkg --compare-versions $v gt $gavail; then
        gavail=$v
      fi
    done
  fi

  if [ "$gavail" == "$ver" ]; then
    echo SU: $name \($ver\)
    continue
  fi

  found=0
  for v in $avail; do
    if [ "$v" == "$ver" ]; then
      echo SA: $name \($ver $gavail\)
      found=1
      break
    fi
  done

  if [ "$found" == "1" ]; then
    continue
  else
    echo NN: $name \($ver\) \($avail\)
  fi
done

## cleanup
#rm -rf apt
