#!/bin/bash

set -e

# lib32asound2-plugins excluded since it depends on ia32-libs

DEBS="$(cat packages.list)"

LIST=sources.list.deb
if [ -e sources.list.local ]; then
  LIST=sources.list.local
fi

export APTDIR=`pwd`/apt
mkdir -p $APTDIR/etc/preferences.d $APTDIR/etc/apt.conf.d
#clear Apt;
#clear Aquire;
#clear Dir;
#clear Dpkg;
#clear Debug;
cat >$APTDIR/etc/apt.conf <<EOF
Dir "$APTDIR/"
{
	State "state"
	{
		status "status";
	};
	Etc "etc/" {
		SourceList "`pwd`/$LIST";
	};
	Cache "cache";
}
Debug
{
	NoLocking "true";
}
Acquire
{
	Retries "3";
}
APT
{
	Architecture "amd64";
	Install-Recommends "false";
}
EOF

export APT_CONFIG=$APTDIR/etc/apt.conf

rm -rf pkgs
mkdir pkgs
rm -rf srcs
mkdir srcs

#APT_GET="apt-get --assume-yes -c=$APTDIR/etc/apt.conf"
APT_GET="apt-get --assume-yes"

# Prepare APTDIR
mkdir -p $APTDIR/state/lists/partial
mkdir -p $APTDIR/cache/archives/partial
echo -n > $APTDIR/state/status
# Bootstrap APT keystore with the one from the local system
cp -a /etc/apt/trusted.gpg $APTDIR/etc/

APT_GET="$APT_GET"

$APT_GET update
$APT_GET autoclean

APT_CACHE="apt-cache -c=$APTDIR/etc/apt.conf"

######################################################################
# Sources

# Fetch sources for all debs
for DEB in $DEBS; do
    # Filter out debs in local/pkgs
    if [ -e local/pkgs/${DEB}_*.deb ]; then
	# Make sure we don't ship an old version
        if VER=$($APT_CACHE 2>/dev/null show $DEB | grep-dctrl "" -n -s Version); then
            VER2=$(dpkg -I local/pkgs/${DEB}_*.deb | grep "^ Version:" | cut -b11-)
	    if dpkg --compare-versions "$VER" ">=" "$VER2"; then
		echo >&2 "$DEB has older version in local than in Debian!"
		exit 1
	    fi
	    echo >&2 "$DEB has newer version in local than in Debian"
	fi
    else
	# Deb needs fetching
        echo $DEB
    fi
done \
| xargs $APT_CACHE show \
| grep-dctrl "" -s Package,Version,Source \
| while read KEY VAL; do # ^ Get package information, needed fields and parse
    # Source: is optional and may not contain a version
    # Fill in missing information from Package and Version
    case "$KEY" in
      Package:) PKG="$VAL"; SRC="$VAL";;
      Version:) VER=$(echo "$VAL" | sed 's/+b[0-9]*$//');;
      Source:) case "$VAL" in
		 *\(*\)) SRC=$(echo "$VAL" | cut -d" " -f1)
			 VER=$(echo "$VAL" | sed 's/.*(\(.*\))/\1/' | sed 's/+b[0-9]*$//');;
		 "") ;;
		 *) SRC="$VAL";;
	       esac;;
      "") echo >&2 "Fetching source $SRC $VER for $PKG"
	  echo "$SRC $VER";;
    esac
  done \
| { sort -u; echo; } \
| while read SRC VER; do # Filter out old version of duplicate sources
    if [ "$SRC" = "$LAST_SRC" ]; then
      if dpkg --compare-versions "$LAST_VER" "<<" "$VER"; then
	echo >&2 "Skipping $SRC $LAST_VER for $VER"
	LAST_VER="$VER"
      else
	echo >&2 "Keeping $SRC $LAST_VER for $VER"
      fi
    else
      echo "$LAST_SRC=$LAST_VER"
      LAST_SRC="$SRC"
      LAST_VER="$VER"
    fi
  done | tail --lines +2 | (cd srcs; xargs $APT_GET -d source) || exit 1 # Fetch source

######################################################################
# fetch prebuild debs
$APT_GET --download-only install $DEBS

# Move only the wanted debs out of cache and clean up
for pkg in $DEBS; do
  cp $APTDIR/cache/archives/${pkg}_*.deb pkgs/
done
#rm -rf $APTDIR

# Sanity check that we have _matching_ source for every deb.
# With debs in local this can happen.

dpkg-scanpackages pkgs /dev/null 2>/dev/null \
| grep-dctrl "" -s Package,Version,Source \
| while read KEY VAL; do
    case "$KEY" in
      Package:) PKG="$VAL"; SRC="$VAL";;
      Version:) VER="$(echo "$VAL" | sed 's/+b[0-9]*$//')";;
      Source:) case "$VAL" in
		 *\(*\)) SRC=$(echo "$VAL" | cut -d" " -f1)
			 VER=$(echo "$VAL" | sed 's/.*(\(.*\))/\1/' | sed 's/+b[0-9]*$//');;
		 "") ;;
		 *) SRC="$VAL";;
	       esac;;
      "") echo "Testing source $SRC $VER for $PKG"
	  FVER=$(echo "$VER" | cut -d: -f2)
	  if [ ! -e "local/srcs/${SRC}_${FVER}.dsc" ]; then
	    if [ ! -e "srcs/${SRC}_${FVER}.dsc" ]; then
	      echo "Missing source $SRC $VER for $PKG!"
	      exit 1
	    fi
	  fi;;
    esac
  done || exit 1

# Get last version and compute new version
LAST_VERSION="$(dpkg-parsechangelog | sed -n 's/^Version: \(.*\)/\1/p')"
NEW_VERSION="$(date +"%Y%m%d")"
if [ "$LAST_VERSION" = "$NEW_VERSION" ]; then
  NEW_VERSION="$LAST_VERSION.1"
fi
if dpkg --compare-versions "$LAST_VERSION" ">=" "$NEW_VERSION"; then
  NEW_VERSION="${LAST_VERSION%.*}.$((${LAST_VERSION##*.}+1))"
fi
if dpkg --compare-versions "$LAST_VERSION" ">=" "$NEW_VERSION"; then
  echo "$LAST_VERSION not less than $NEW_VERSION"
  exit 1
fi

# Are we done or are there any new packages?
if ! [ -f "versions/$LAST_VERSION" ]; then
  echo "versions/$LAST_VERSION: No such file or directory."
  echo "Did you manually create a new changelog entry and forgot to create that file?"
  echo "Fetch failed!"
  exit 1
fi
cd srcs
find ./ -name "*.dsc" | sort | while read src; do
  PKG=$(grep "^Source:" "$src" | cut -d" " -f2)
  VER=$(grep "^Version:" "$src" | head --lines 1 | cut -d" " -f2)
  OLD_VER=$(grep "^$PKG " "../versions/$LAST_VERSION" | cut -d" " -f2)
  if [ "$OLD_VER" = "$VER" ]; then
    continue
  fi
  echo "New source $PKG $VER"
  echo -n > "../versions/$NEW_VERSION"
done
cd ..

if ! [ -f  "versions/$NEW_VERSION" ]; then
  echo "No source updates, all done"
  echo "All sources fetched, all packages fetched, all versions match."
  echo "Enjoy."
  exit 0
fi

echo "New sources found. Generating changelog and copyright."
# Create new changelog entry
dch --newversion "$NEW_VERSION" --distribution UNRELEASED --multimaint --maintmaint "Packages updated"

# Create versions list, copyright and changelogs
cp debian/copyright.header debian/copyright.tmp
echo -n > "versions/$NEW_VERSION"
cd srcs
find ./ -name "*.dsc" | sort | while read src; do
  PKG=$(grep "^Source:" "$src" | cut -d" " -f2)
  VER=$(grep "^Version:" "$src" | head --lines 1 | cut -d" " -f2)
  echo "$PKG $VER" >> "../versions/$NEW_VERSION"
  OLD_VER=$(grep "^$PKG " "../versions/$LAST_VERSION" | cut -d" " -f2)

  # Extract copyright
  echo "'$PKG' '$OLD_VER' -> '$VER'"
  tmpdir=$(mktemp -d)
  dpkg-source -x "$src" "$tmpdir/src" >/dev/null 2>&1
  if [ -e "$tmpdir/src/debian/copyright" ]; then
    echo "---------------------------------------------------------------" >> ../debian/copyright.tmp
    echo "Copyright for $src" >> ../debian/copyright.tmp
    cat "$tmpdir/src/debian/copyright" >> ../debian/copyright.tmp
  else
    # Check for a manually extracted copyright file
    pname=$(echo "$src" | cut -d_ -f1)
    if [ -e "../debian/copyrights/$pname" ]; then
            echo "Using overriden copyright file for $src"
            echo "---------------------------------------------------------------" >> ../debian/copyright.tmp
            echo "Copyright for $src" >> ../debian/copyright.tmp
            cat "../debian/copyrights/$pname" >> ../debian/copyright.tmp
    else
        echo "WARNING: Copyright missing for $src"
        touch "../COPYRIGHTERROR"
    fi
  fi

  # Extract changelog
  if [ "$OLD_VER" = "" ]; then
    echo  New package, no old versions
    sed '/^  \* Packages updated$/,$d' ../debian/changelog > ../debian/changelog.new
    echo "  * Add $PKG $VER" >> ../debian/changelog.new
    sed --quiet '/^  \* Packages updated$/,$p' ../debian/changelog >> ../debian/changelog.new
    mv ../debian/changelog.new ../debian/changelog
  elif ! [ "$VER" = "$OLD_VER" ]; then
    # Old package, extract changelog
    sed '/^ --/,$d' ../debian/changelog > ../debian/changelog.new
    dpkg-parsechangelog --since "$OLD_VER" -l"$tmpdir/src/debian/changelog" \
    | sed 's/^/#/' \
    | while read LINE; do
        case "$LINE" in
	  ("# .") echo "# ";;
	  ("#  "*) echo "$LINE";;
	  ("# "*) echo "$LINE" | while read foo PKG VER REL URG; do
	      echo "#   [ $PKG $VER $REL $URG ]"
	  done;;
        esac
    done | sed 's/[Cc]loses: *//g' | cut -b3- >> ../debian/changelog.new
    echo >> ../debian/changelog.new
    sed --quiet '/^ --/,$p' ../debian/changelog >> ../debian/changelog.new
    mv ../debian/changelog.new ../debian/changelog
  fi
  # Cleanup
  rm -fr $tmpdir
done
cd ..

if [ -f "COPYRIGHTERROR" ]; then
    rm "COPYRIGHTERROR"
    echo "ERROR: Some copyright file is missing.  Do not upload"
    exit 1
fi

mv debian/copyright.tmp debian/copyright

echo "All sources fetched, all packages fetched, all versions match."
echo "New changelog created."
echo "Enjoy."
exit 0
