#!/bin/bash

# Usage: dasource [-r REPOS] [PACKAGENAME ...]

# Creates or updates a checkout and source package for each listed
# PACKAGENAME, or for all regular packages if no PACKAGENAME is
# specified.

# If REPOS is specified, it is used in preference to the canonical
# Athena repository trunk.

# Package subdirectories are created in the cwd.  The source checkout
# will reside in PACKAGENAME/PACKAGENAME-VERSION and the source
# package will be created in PACKAGENAME.

set -e

trap 'echo "dasource failed: Source package _not_ created"' EXIT

die() {
  echo "$@" >&2
  exit 1
}

usage() {
  die "dasource [-r repos] [packagename ...]"
}
: ${DA_SCRIPTS_DIR="$(dirname "$(readlink -f "$0")")"}
basedir="$DA_SCRIPTS_DIR"
repo=git+ssh://git.mit.edu

while getopts r: opt; do
  case "$opt" in
  r)
    repo="$OPTARG"
    ;;
  \?)
    usage
    ;;
  esac
done
shift $(($OPTIND - 1))

do_package() {
  pkgname=$1
  pkgpath=$2
  if [ ! -d $pkgname ]; then
    echo "Creating directory $pkgname"
    mkdir $pkgname
  fi

  # Work around a bad interaction between dpkg-source and AFS.
  # (dpkg-source invokes perl's Tempfile which checks if the parent
  # directory is writable using mode bits).  This will not actually
  # grant any outside access to the directory since AFS ignores
  # non-user mode bits.
  if fs whichcell . >/dev/null 2>&1; then
    chmod 777 $pkgname
  fi

  # Check out or update the package source.
  pattern="$pkgname/$pkgname-[0-9]*[0-9]"
  if [ $(echo $pattern | wc -w) -gt 1 ]; then
    die "More than one checkout under $pkgname!"
  elif [ -d $pattern ]; then
    dir=$(echo $pattern)
    if [ -d "${dir}/.svn" ]; then
	echo "Old SVN checkout found.  Killing with fire..."
	rm -rf "$dir"
	dir=$pkgname/$pkgname
	echo "Checking out $repo$pkgpath into $dir"
	git clone $repo$pkgpath $dir
    else
	echo "Updating and cleaning $dir"
	(cd $dir && git checkout -f && git pull)
    fi
  else
    dir=$pkgname/$pkgname
    echo "Checking out $repo$pkgpath into $dir"
    git clone $repo$pkgpath $dir
  fi

  # Ensure that we're not trying to do something stupid
  distribution=$(cd $dir && dpkg-parsechangelog | sed -n 's/Distribution: //p')
  if [ "$distribution" = "UNRELEASED" ]; then
    echo "You can't/shouldn't build a package marked as UNRELEASED."
    exit 1
  fi

  # Extract the changelog version and strip off the epoch and Debian component.
  changever=$(cd $dir && dpkg-parsechangelog | sed -n 's/Version: //p')
  sver=$(echo $changever | sed -re 's/^[0-9]+://p')
  upver=$(echo $sver | sed -re 's/-[^-]*$//')

  # Rename the source checkout if necessary.
  correctdir=$pkgname/${pkgname}-$upver
  if [ $dir != $correctdir ]; then
    echo "Renaming $dir to $correctdir"
    mv $dir $correctdir
    dir=$correctdir
  fi

  # TODO: Sanity-check that the version in configure.ac matches the
  #       upstream version

  # Add autoconf goo if it's an Athena source directory.
  # We can no longer determine this from the repo path
  if [ -e "$dir/configure.in" ] && ! [ -e "$dir/configure.ac" ] \
      && ! [ -e "$dir/configure" ]; then
      (cd $dir && $basedir/daconfiscate)
  fi

  # Generate debian/control from debian/control.in if control.in exists
 [ -f "$dir/debian/control.in" ] && echo "NOTE: Obsolete CDBS package -- convert to DH7!"
  ([ -f "$dir/debian/control.in" ] && cd $dir && DEB_AUTO_UPDATE_DEBIAN_CONTROL=yes debian/rules debian/control || :)
  [ -f "$dir/debian/control" ] || die "Can't find or generate debian/control!"

  # Read in debian-versions
  . $basedir/debian-versions.sh

  NOBUILD=$(grep-dctrl -n -s X-Debathena-No-Build -F X-Debathena-No-Build -e . "$dir/debian/control" || true)
  BUILDFOR=$(grep-dctrl -n -s X-Debathena-Build-For -F X-Debathena-Build-For -e . "$dir/debian/control" || true)
  if [ -n "$NOBUILD" ] && [ -n "$BUILDFOR" ]; then
      echo "It is an error to specify both X-Debathena-Build-For and"
      echo "X-Debathena-No-Build.  Pick one and try again."
      die
  elif [ -z "$NOBUILD" ] && [ -z "$BUILDFOR" ]; then
      [ -f "$pkgname/nobuild" ] && echo "NOTE: Please migrate legacy ./nobuild to X-Debathena-No-Build!"
  else
      [ -f "$pkgname/nobuild" ] && rm "$pkgname/nobuild"
      if [ -n "$BUILDFOR" ]; then
	  NOBUILD=
	  for code in $DEBIAN_CODES; do
	      if ! echo "$BUILDFOR" | fgrep -q "$code"; then
		  NOBUILD="$NOBUILD $code"
	      fi
	  done
      fi
      echo "$NOBUILD" > "$pkgname/nobuild"
  fi

  # Create a suitable orig tarball if necessary.
  (cd $dir && $basedir/daorig)

  # Build an unsigned package, ignoring version control subdirs in the source.
  echo "Creating source package"
  (cd $dir && debuild -S -i -I -sa -us -uc)

  if grep '^Architecture: ' $dir/debian/control | grep -q -v 'Architecture: all'; then
    echo "At least one arch-dependent binary package; run sbuildhack WITHOUT -A." >&2
  elif grep -q '^Architecture: ' $dir/debian/control; then
    echo "No arch-dependent binary packages; run sbuildhack with -A." >&2
  else
    echo "No binary packages???" >&2
  fi
}

packages=packages

if [ ! -r "$packages" ]; then
    packages=/mit/debathena/packages/packages
fi
if [ ! -r "$packages" ]; then
  die "Can't read packages file; create with gen-packages"
fi

if [ $# -gt 0 ]; then
  # Build specific source packages.
  for pkgname; do
    pkgname="${pkgname%/}"
    pkgpath=$(sed -nre "s/^$pkgname[[:space:]]+//p" "$packages")
    if ! [ -n "$pkgpath" ]; then
	echo "Can't find package $pkgname" >&2
	echo >&2
	echo "This may be because the list of packages is not up to date. If" >&2
	echo "this is a new package, and you have the bits, run gen-packages" >&2
	echo "with /mit/debathena/packages as your working directory." >&2
	echo "Otherwise, run gen-packages in this directory and dasource will" >&2
	echo "use the generated file instead." >&2
	die
    fi
    do_package $pkgname $pkgpath
  done
else
  echo -n "Really build ALL source packages? (y/N) "
  read answer
  if [ "$answer" = "y" ]; then
  # Build all source packages.
    exec <"$packages"
    while read pkgname pkgpath; do
      do_package $pkgname $pkgpath
    done
  fi
fi
# Unset trap
trap - EXIT
