#!/bin/sh

# Input:
#   distribution (default sid)
#   architecture (default amd64)
#   force_update (default false)

set -eu

error () {
  echo "Error: $@" >&2
  exit 1
}

# read pgapt config
for dir in . .. $HOME/apt.postgresql.org; do
  test -f $dir/pgapt.conf || continue
  . $dir/pgapt.conf
  break
done
chroot="source:${distribution:=sid}-${architecture:=$(dpkg --print-architecture)}-sbuild"
chroot_path="/home/chroot/$distribution-$architecture"
set_dist_vars $distribution $architecture

# check if chroot is configured in sbuild
schroot -l | grep -q $chroot || \
  error "There is no schroot definition for $chroot (run schroot-config.sh first)"

if [ "${force_update:-false}" = "false" ]; then
  timeout="--timeout=10"
fi

# build package and run autopkgtests inside the chroot
# (lock against concurrent apt-get update/upgrade operations and builds)
LOCKDIR="/var/lock/sbuild-package"
if ! test -d $LOCKDIR; then
  mkdir $LOCKDIR
  chgrp sbuild $LOCKDIR
  chmod 3775 $LOCKDIR
fi
umask 002

(
  cd /
  set -x
  if ! flock ${timeout:-} --exclusive 9; then # lock against concurrent access
    : "Chroot $chroot is locked, giving up for now"
    exit
  fi

  # create chroot if it doesn't exist yet
  if ! test -d $chroot_path; then
    echo "Creating chroot in $chroot_path"
    if ! test -e /usr/share/debootstrap/scripts/$distribution; then
      case $DISTRO in
        debian) sudo ln -sv sid /usr/share/debootstrap/scripts/$distribution ;;
        ubuntu) sudo ln -sv gutsy /usr/share/debootstrap/scripts/$distribution ;;
      esac
    fi
    sudo debootstrap --variant=buildd --arch=$architecture $distribution $chroot_path $mirror
  fi

  # do the update
  schroot -u root -c $chroot -- sh <<-EOF
	set -ex
	
	# tell debconf and ucf not to ask any questions
	export DEBIAN_FRONTEND=noninteractive

	# configure dpkg and apt
	test -e /etc/dpkg/dpkg.cfg.d/01unsafeio || echo force-unsafe-io | tee /etc/dpkg/dpkg.cfg.d/01unsafeio
	test -e /etc/apt/apt.conf.d/20dpkg || echo 'DPkg::Options:: "--force-confnew"; DPkg::Options:: "--force-confmiss";' | tee /etc/apt/apt.conf.d/20dpkg
	test -e /etc/apt/apt.conf.d/20norecommends || echo 'APT::Install-Recommends "false";' | tee /etc/apt/apt.conf.d/20norecommends
	test -e /etc/apt/apt.conf.d/50i18n || echo 'Acquire::Languages { none; };' | tee /etc/apt/apt.conf.d/50i18n
	test -e /etc/apt/apt.conf.d/60releaseinfo || echo 'Acquire::AllowReleaseInfoChange "true" { Suite "true"; };' | tee /etc/apt/apt.conf.d/60releaseinfo # don't complain when testing gets released as stable
	rm -f /var/lib/apt/lists/*_Translation-*

	# write sources lists
	echo "deb $mirror $distribution main" > /etc/apt/sources.list
	case $DISTRO in
	  ubuntu) # libossp-uuid-dev is in universe on vivid+
	    echo "deb $mirror $distribution universe" > /etc/apt/sources.list.d/universe.list
	    echo "deb $mirror $distribution-updates main universe" > /etc/apt/sources.list.d/updates.list
	    echo "deb $mirror $distribution-security main universe" > /etc/apt/sources.list.d/security.list
	    ;;
	  *)
	    if [ "${dist_security:-}" ]; then
	      echo "deb ${security:-} ${dist_security:-} main" > /etc/apt/sources.list.d/security.list
	    else
	      echo "# no security support for $distribution/$architecture" > /etc/apt/sources.list.d/security.list
	    fi
	    ;;
	esac
	if [ "$HAS_BACKPORTS" ]; then
	  echo "${mirror_backports:-}" > /etc/apt/sources.list.d/backports.list
	  if [ -d /var/lib/apt/backports ]; then
	    rm -f /var/lib/apt/lists/*backports* # clean up if last run failed
	    cp -al /var/lib/apt/backports/* /var/lib/apt/lists
	  fi
	else
	  rm -f /etc/apt/sources.list.d/backports.list*
	fi

	# run apt.postgresql.org.sh to install repository key (ca-certificates for https:// repo URL)
	if ! test -f /etc/apt/sources.list.d/pgdg.sources; then
	  apt-get install -y ca-certificates postgresql-common gnupg
	  echo | /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh # installed version might not know -h yet
	  apt-get install -y postgresql-common gnupg-
	  /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -h$PGDG_MIRROR -st $distribution
	fi

	# add a local extra repo
	if [ "${LOCAL_REPO:-}" ]; then
	  keyring="/etc/apt/keyrings/${LOCAL_REPO_NAME:-}.asc"
	  echo "deb [signed-by=\$keyring] ${LOCAL_REPO:-} $distribution main" > /etc/apt/sources.list.d/${LOCAL_REPO_NAME:-}.list
	  echo "deb-src [signed-by=\$keyring] ${LOCAL_REPO:-} $distribution main" >> /etc/apt/sources.list.d/${LOCAL_REPO_NAME:-}.list
	  echo "${LOCAL_REPO_KEY:-}" > \$keyring
	  cat > /etc/apt/preferences.d/${LOCAL_REPO_NAME:-}.pref << EOT
Package: *
Pin: release o=$REPO_ORIGIN
Pin-Priority: 600
EOT
	fi

	# try update twice because ubuntu mirrors keep acting up
	apt-get -y update || { sleep 60; apt-get -y update; }

	# save backports lists
	rm -rf /var/lib/apt/backports /etc/apt/sources.list.d/backports.list.disabled
	if [ "$HAS_BACKPORTS" ]; then
	  mv /etc/apt/sources.list.d/backports.list /etc/apt/sources.list.d/backports.list.disabled
	  mkdir -p /var/lib/apt/backports
	  mv /var/lib/apt/lists/*backports* /var/lib/apt/backports
	fi
	
	apt-get -y dist-upgrade
	apt-get -y install pgdg-buildenv lintian-
	apt-get -y autoremove --purge

	# overwrite ucf.conf (the package ships its own file)
	cat > /etc/ucf.conf <<EOT
conf_force_conffnew=y
conf_force_conffmiss=y
EOT

	# revert Ubuntu's default zstd compression for .debs
	if dpkg-deb --help | grep zstd; then
	  if grep "my @dpkg_options;" /usr/bin/dh_builddeb; then
		sed -i -e "s/my @dpkg_options;/my @dpkg_options = ('-Zxz');/" /usr/bin/dh_builddeb
	  fi
	  if grep "@dbgsym_dpkg_options = ('--root" /usr/bin/dh_builddeb; then
		sed -i -e "s/ @dbgsym_dpkg_options = ('--root/ @dbgsym_dpkg_options = ('-Zxz', '--root/" /usr/bin/dh_builddeb
	  fi
	fi
	
	# remove libreadline-dev if present
	if dpkg -l 'libreadline*-dev' | grep -q '^ii'; then
	  apt-get remove -y 'libreadline*-dev'
	fi

	# install PostgreSQL
	apt-get -y install postgresql-common
	apt-get -y install $CHROOT_INSTALL_PKGS # separate step to ease bootstrapping

	apt-get clean
	dpkg -l 'libpq*' 'newpid' 'pgdg*' 'postgresql*' 'libreadline*' 'libedit*' '*llvm*' '*clang*' || :

	EOF
) 9> $LOCKDIR/$distribution-$architecture.lock
