#!/bin/bash

[ $# -eq 1 ] || { echo "must give version"; exit 1; }

VER=$1
daily=false
if [ "$1" = "daily" ]; then
   VER="d$(date +%y%m%d)"
   daily=true
fi
pre=cirros-$VER
BR_VER="2015.05"
ARCHES="${ARCHES:-i386 x86_64 arm powerpc aarch64 ppc64 ppc64le}"
KVER="3.19.0-20.20~14.04.1"
ME=$(readlink -f "$0")
MY_D=${ME%/*}
PATH=${MY_D}:$PATH

dl() {
   local url="$1" target="$2" tfile="" t=""
   [ -f "$target" ] && return
   t=$(dirname "$target")
   tfile=$(mktemp "$t/.${0##*/}.XXXXXX") || return
   wget "$url" -O "$tfile" &&
      mv "$tfile" "$target" ||
      { t=$?; rm -f "$tfile"; return $t; }
}
msg() {
   echo "$@" >> "$LOGFILE"
   echo "$@"
}
logevent() {
   # logevent(msg, [from])
   # log the message in $1 and time since $2, defaulting to last call.
   local up delta msg="$1" ref="$2"
   up=${SECONDS}
   if [ "$ref" = "-" ]; then
      ref=""
   elif [ "$ref" = "" ]; then
      ref="${_LAST_UP}"
   fi
   if [ -n "$ref" ]; then
      delta="$(($up-$ref))"
   fi
   msg "$(date -R)" "$msg" "${delta:+[${delta}s]}"
   _LAST_UP=$up
   _RET=${_LAST_UP}
}

error() { echo "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }

set -e
set -o pipefail

out="$PWD/../build-$VER"
LOGFILE="$out/date.txt"
export TMPDIR="$out/tmp"
mkdir -p "$out" "$TMPDIR"

# really just here to check that VER is a tag
# or source code checkout would fail
if ! $daily; then
    revno=$(bzr tags -r "tag:$VER") || fail "$VER: not a tag in $PWD."
    revno=$(echo "$revno" | awk '{print $2}')
fi

logevent "begin" -
tstart=${_RET}

logevent "start download" -
rm -f download
mkdir -p ../download
ln -snf ../download download
brtgz="buildroot-${BR_VER}.tar.gz"
dl "http://buildroot.uclibc.org/downloads/$brtgz" "download/$brtgz"
logevent "end download"

logevent "start unpack" -
rm -Rf "buildroot-${BR_VER}"
rm -f buildroot
tar -xvf download/buildroot-${BR_VER}.tar.gz
ln -snf buildroot-${BR_VER} buildroot

# we do not do this here, so that we're not dependent on the
# cvs working (which wont work through http_proxy) and also
# to have revision controlled information in that file.
#./bin/mkcabundle > src/etc/ssl/certs/ca-certificates.crt

( cd buildroot && QUILT_PATCHES="$PWD/../patches-buildroot" quilt push -a )

echo "$VER" > "src/etc/cirros/version"
logevent "end unpack"

logevent "start br-source" -
make ARCH=i386 br-source
logevent "end br-source"

logevent "start kernel download" -
grab-kernels "$KVER" ${ARCHES}
logevent "end kernel download"

for arch in ${ARCHES}; do
  logevent "start $arch" -
  time make ARCH=$arch "OUT_D=$out/build/$arch" \
    ${CCACHE_D:+"BR2_CCACHE_DIR=${CCACHE_D}/$arch"} 2>&1 |
     tee "$out/build-$arch.log";
  ret=$?
  logevent "finish $arch [ret=$ret]"
done;

for arch in ${ARCHES}; do
  mkdir -p "$out/stage/$arch"
done

logevent "start bundling" -
for arch in ${ARCHES}; do
  case "$arch" in
     powerpc|ppc*|aarch64) size=64M;;
     *) size="";;
  esac
  sudo ./bin/bundle -v ${size:+--size=$size} --arch="$arch" \
     "$out/build/$arch/rootfs.tar" \
     ./download/kernel-$arch.deb "$out/stage/$arch";
done
logevent "finish bundling"

sudo chown -R $USER:$USER "$out/stage"

mkdir -p "$out/release"

#srctgz="$out/release/cirros-$VER-source.tar.gz"
#bzr export -r "tag:$VER" --format=tgz --root="cirros-$VER" "$srctgz"
#echo "wrote source tgz: $srctgz"
if ! $daily; then
  ( srcd="$PWD" && tmpd=$(mktemp -d) && cd "$tmpd" &&
    bzr branch "$srcd" -r tag:$VER cirros-$VER &&
    rm -Rf cirros-$VER/.bzr &&
    echo "$VER" > "cirros-$VER/src/etc/cirros/version" &&
    tar cvzf - cirros-$VER ) > "$out/release/cirros-$VER-source.tar.gz"
fi

rm -f "$out/stage"/*/"$pre"*
for arch in ${ARCHES}; do
  p=$pre-$arch
  ( cd "$out/stage/$arch" &&
    ln kernel $p-vmlinuz && ln kernel $p-kernel &&
    ln initramfs $p-initrd && ln initramfs $p-initramfs &&
    ln part.img $p-rootfs.img &&
    ln blank.img $p-blank.img &&
    ln disk.img $p-disk.img &&
    ln filesys.tar.gz $p-lxc.tar.gz &&
    true
  ); done

logevent "start populating release" -
for arch in ${ARCHES}; do
  p=$pre-$arch
  ( cd "$out/stage/$arch" &&
    cp $p-kernel $p-initramfs $p-lxc.tar.gz "$out/release/" &&
    gzip -9 -c $p-rootfs.img > $out/release/$p-rootfs.img.gz ) &&
  ( cd "$out/stage/$arch" &&
    tar cvzf - $p-blank.img $p-vmlinuz $p-initrd ) > \
    "$out/release/$p-uec.tar.gz"
  [ "$arch" = "arm" ] ||
     cp "$out/stage/$arch/$p-disk.img" "$out/release/$p-disk.img"
done

mkdir -p "$out/release/buildroot_rootfs"
for arch in ${ARCHES}; do
  t="$out/release/buildroot_rootfs/buildroot-$VER-$arch.tar"
  cp "$out/build/$arch/rootfs.tar" "$t" && gzip --force -9 "$t"
done

chmod u+rwX,go+rX -R "$out/release/"* 

sumfiles=$(cd "$out/release" && for f in *; do
   [ -f "$f" -a "$f" != MD5SUMS ] && echo "$f"; done)
( cd "$out/release" && md5sum $sumfiles > MD5SUMS )

logevent "finish populate release" -
msg "output in $out/release"
msg "entire process took $SECONDS seconds"
logevent "finished" "$tstart"
