#! /usr/bin/env bash

# Create ODB source distributions
#
# -rebuild
# -complete  package/build libcutl and the ODB compiler; implies -rebuild
# -test
# -db <database>
# -odb <odb-compiler-path>
# -cxx <c++-compiler>
# -cxxp <g++-plugin-compiler>
#
trap 'exit 1' ERR

function error ()
{
  echo "$*" 1>&2
}

# Find output directory for a project. It is either $1-default or if
# that doesn't exist, it is $1.
#
function find_out_dir ()
{
  # Get the actual directory in case -default is a symlink.
  #
  tmp=`realpath $1-default 2>/dev/null`

  if [ -n "$tmp" -a -d "$tmp" ]; then
    echo "$tmp"
  else
    echo "$1"
  fi
}

wd=`pwd`
out_root=/tmp
src_root=$HOME/work/odb
ver=`sed -e 's/^\(.*\)\.\(.*\)\..*$/\1.\2/' $src_root/odb/version`

test=n
rebuild=n
complete=n
db=
odb=$src_root/odb/odb/odb
cxx=g++
cxxp=g++-4.5

CXXFLAGS="-W -Wall -Wno-unknown-pragmas"

while [ $# -gt 0 ]; do
  case $1 in
    -rebuild)
      rebuild=y
      shift
      ;;
    -complete)
      rebuild=y
      complete=y
      shift
      ;;
    -test)
      test=y
      shift
      ;;
    -db)
      shift
      db="$db $1"
      shift
      ;;
    -odb)
      shift
      odb=$1
      shift
      ;;
    -cxx)
      shift
      cxx=$1
      shift
      ;;
    -cxxp)
      shift
      cxxp=$1
      shift
      ;;
    *)
      error "unknown option: $1"
      exit 1
      ;;
  esac
done

if [ "$db" = "" ]; then
  db="pgsql sqlite mysql"
fi

# Clean everything up if we are rebuilding.
#
if [ $rebuild = y ]; then
  rm -rf $out_root/libodb/*
  rm -rf $out_root/libodb-pgsql/*
  rm -rf $out_root/libodb-sqlite/*
  rm -rf $out_root/libodb-mysql/*
  rm -rf $out_root/libodb-boost/*
  rm -rf $out_root/libodb-qt/*
  rm -rf $out_root/odb-tests/* $out_root/odb-tests-*
  rm -rf $out_root/odb-examples/* $out_root/odb-examples-*

  if [ $complete = y ]; then
    rm -rf $out_root/libcutl/*
    rm -rf $out_root/odb/*
  fi

  rm -rf $out_root/pack
fi

mkdir -p $out_root/libodb
mkdir -p $out_root/libodb-pgsql
mkdir -p $out_root/libodb-sqlite
mkdir -p $out_root/libodb-mysql
mkdir -p $out_root/libodb-boost
mkdir -p $out_root/libodb-qt
mkdir -p $out_root/odb-tests
mkdir -p $out_root/odb-examples

if [ $complete = y ]; then
  mkdir -p $out_root/libcutl
  mkdir -p $out_root/odb
fi

mkdir -p $out_root/pack

# Build libcutl
#
if [ $complete = y ]; then
  cd $src_root/../cutl
  ./dist.sh $out_root/libcutl
  cd $wd
fi

# Build ODB compiler
#
if [ $complete = y ]; then
  make -C `find_out_dir $src_root/odb` -f $src_root/odb/makefile \
dist dist_prefix=$out_root/odb

  cd $out_root/odb

  ./bootstrap
  ./configure --with-libcutl=../libcutl CXX=$cxxp CXXFLAGS="$CXXFLAGS"

  make -j 8
  make dist

  cd $wd

  cp $out_root/odb/odb-$ver.*.zip $out_root/pack/
  cp $out_root/odb/odb-$ver.*.tar.gz $out_root/pack/
  cp $out_root/odb/odb-$ver.*.tar.bz2 $out_root/pack/

  odb=$out_root/odb/odb/odb
fi

# Build libodb
#
make -C `find_out_dir $src_root/libodb` -f $src_root/libodb/makefile \
dist dist_prefix=$out_root/libodb

cd $out_root/libodb

if [ $rebuild = y ]; then
  ./bootstrap
  ./configure CXX=$cxx CXXFLAGS="$CXXFLAGS"
fi

make -j 8
make dist

cd $wd

cp $out_root/libodb/libodb-$ver.*.zip $out_root/pack/
cp $out_root/libodb/libodb-$ver.*.tar.gz $out_root/pack/
cp $out_root/libodb/libodb-$ver.*.tar.bz2 $out_root/pack/

# Build libodb-pgsql
#
make -C `find_out_dir $src_root/libodb-pgsql` \
-f $src_root/libodb-pgsql/makefile dist dist_prefix=$out_root/libodb-pgsql

cd $out_root/libodb-pgsql

if [ $rebuild = y ]; then
  ./bootstrap
  ./configure --with-libodb=../libodb CXX=$cxx CXXFLAGS="$CXXFLAGS"
fi

make -j 8
make dist

cd $wd

cp $out_root/libodb-pgsql/libodb-pgsql-$ver.*.zip $out_root/pack/
cp $out_root/libodb-pgsql/libodb-pgsql-$ver.*.tar.gz $out_root/pack/
cp $out_root/libodb-pgsql/libodb-pgsql-$ver.*.tar.bz2 $out_root/pack/

# Build libodb-sqlite
#
make -C `find_out_dir $src_root/libodb-sqlite` \
  -f $src_root/libodb-sqlite/makefile dist dist_prefix=$out_root/libodb-sqlite

cd $out_root/libodb-sqlite

if [ $rebuild = y ]; then
  ./bootstrap
  ./configure --with-libodb=../libodb CXX=$cxx CXXFLAGS="$CXXFLAGS"
fi

make -j 8
make dist

cd $wd

cp $out_root/libodb-sqlite/libodb-sqlite-$ver.*.zip $out_root/pack/
cp $out_root/libodb-sqlite/libodb-sqlite-$ver.*.tar.gz $out_root/pack/
cp $out_root/libodb-sqlite/libodb-sqlite-$ver.*.tar.bz2 $out_root/pack/

# Build libodb-mysql
#
make -C `find_out_dir $src_root/libodb-mysql` \
-f $src_root/libodb-mysql/makefile dist dist_prefix=$out_root/libodb-mysql

cd $out_root/libodb-mysql

if [ $rebuild = y ]; then
  ./bootstrap
  ./configure --with-libodb=../libodb CXX=$cxx CXXFLAGS="$CXXFLAGS"
fi

make -j 8
make dist

cd $wd

cp $out_root/libodb-mysql/libodb-mysql-$ver.*.zip $out_root/pack/
cp $out_root/libodb-mysql/libodb-mysql-$ver.*.tar.gz $out_root/pack/
cp $out_root/libodb-mysql/libodb-mysql-$ver.*.tar.bz2 $out_root/pack/

# Build libodb-boost
#
make -C `find_out_dir $src_root/libodb-boost` \
-f $src_root/libodb-boost/makefile dist dist_prefix=$out_root/libodb-boost

cd $out_root/libodb-boost

if [ $rebuild = y ]; then
  ./bootstrap
  ./configure --with-libodb=../libodb CXX=$cxx CXXFLAGS="$CXXFLAGS"
fi

make -j 8
make dist

cd $wd

cp $out_root/libodb-boost/libodb-boost-$ver.*.zip $out_root/pack/
cp $out_root/libodb-boost/libodb-boost-$ver.*.tar.gz $out_root/pack/
cp $out_root/libodb-boost/libodb-boost-$ver.*.tar.bz2 $out_root/pack/

# Build libodb-qt
#
make -C `find_out_dir $src_root/libodb-qt` \
-f $src_root/libodb-qt/makefile dist dist_prefix=$out_root/libodb-qt

cd $out_root/libodb-qt

if [ $rebuild = y ]; then
  ./bootstrap
  ./configure --with-libodb=../libodb CXX=$cxx CXXFLAGS="$CXXFLAGS"
fi

make -j 8
make dist

cd $wd

cp $out_root/libodb-qt/libodb-qt-$ver.*.zip $out_root/pack/
cp $out_root/libodb-qt/libodb-qt-$ver.*.tar.gz $out_root/pack/
cp $out_root/libodb-qt/libodb-qt-$ver.*.tar.bz2 $out_root/pack/

# Build odb-tests
#
make -C `find_out_dir $src_root/tests-mysql` -f $src_root/tests/makefile dist \
dist_prefix=$out_root/odb-tests

cd $out_root/odb-tests

if [ $rebuild = y ]; then
  ./bootstrap
fi

cd $wd

dist_tests=

for d in $db; do
  mkdir -p $out_root/odb-tests-$d
  cd $out_root/odb-tests-$d

  if [ $rebuild = y ]; then
    ../odb-tests/configure \
--with-database=$d \
--with-libodb=../libodb \
--with-libodb-$d=../libodb-$d \
--with-libodb-boost=../libodb-boost \
--with-libodb-qt=../libodb-qt \
CXX=$cxx \
CXXFLAGS="$CXXFLAGS" \
ODB=$odb
  fi

  if [ $test = y ]; then
    make -j 8 check
  fi

  if [ "$dist_tests" = "" ]; then
    dist_tests=$d
    make dist
  fi

  cd $wd
done

cp $out_root/odb-tests-$dist_tests/odb-tests-$ver.*.zip $out_root/pack/
cp $out_root/odb-tests-$dist_tests/odb-tests-$ver.*.tar.gz $out_root/pack/
cp $out_root/odb-tests-$dist_tests/odb-tests-$ver.*.tar.bz2 $out_root/pack/


# Build odb-examples
#
make -C `find_out_dir $src_root/examples-mysql` \
-f $src_root/examples/makefile dist dist_prefix=$out_root/odb-examples

cd $out_root/odb-examples

if [ $rebuild = y ]; then
  ./bootstrap
fi

cd $wd

dist_examples=

for d in $db; do
  mkdir -p $out_root/odb-examples-$d
  cd $out_root/odb-examples-$d

  if [ $rebuild = y ]; then
    ../odb-examples/configure \
--with-database=$d \
--with-libodb=../libodb \
--with-libodb-$d=../libodb-$d \
--with-libodb-boost=../libodb-boost \
--with-libodb-qt=../libodb-qt \
CXX=$cxx \
CXXFLAGS="$CXXFLAGS" \
ODB=$odb
  fi

  if [ $test = y ]; then
    make -j 8 check
  fi

  if [ "$dist_examples" = "" ]; then
    dist_examples=$d
    make dist
  fi

  cd $wd
done

cp $out_root/odb-examples-$dist_examples/odb-examples-$ver.*.zip $out_root/pack/
cp $out_root/odb-examples-$dist_examples/odb-examples-$ver.*.tar.gz $out_root/pack/
cp $out_root/odb-examples-$dist_examples/odb-examples-$ver.*.tar.bz2 $out_root/pack/