#! /usr/bin/env bash

# Create ODB compiler Windows distribution.
#
# -rebuild
# -pack      get the source distributions from /tmp/pack/
#
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
}

rebuild=n
pack=n

while [ $# -gt 0 ]; do
  case $1 in
    -rebuild)
      rebuild=y
      shift
      ;;
    -pack)
      pack=y
      rebuild=y
      shift
      ;;
    *)
      error "unknown option: $1"
      exit 1
      ;;
  esac
done


if [ $pack = n ]; then
  src_root=$HOME/work

  over=`cat $HOME/work/odb/odb/version`
else
  src_root=/tmp

  cver=`echo $src_root/libcutl-?.*.tar.gz | sed -e "s%$src_root/libcutl-\(.*\).tar.gz%\1%"`
  over=`echo $src_root/pack/odb-?.*.tar.gz | sed -e "s%$src_root/pack/odb-\(.*\).tar.gz%\1%"`
  mver=`echo $over | sed -e 's%\([0-9]*\.[0-9]*\).*%\1%'`
fi

out_root=`pwd`
install_root="/tmp/odb-$over-i686-windows"

export PATH=$out_root/cross/mingw/bin:$PATH

# Clean everything up if we are rebuilding.
#
if [ $rebuild = y ]; then
  rm -rf /mingw/*
  rm -rf libplugin-stub
  rm -rf gcc-build/*
  rm -rf libcutl
  rm -rf libodb
  rm -rf libodb-boost
  rm -rf libodb-qt
  rm -rf odb
  rm -rf odb-build/*
  rm -rf $install_root

  cp -r mingw-rt/* /mingw/
  # make -C binutils-build install
  cp -r mingw-binutils/* /mingw/
fi

if [ $pack = n ]; then
  rm -f /tmp/odb-$over-i686-windows.zip
else
  rm -f /tmp/pack/odb-$over-i686-windows.zip
fi

# Build libplugin-stub
#
if [ $rebuild = y ]; then
  mkdir -p libplugin-stub
  cd libplugin-stub
  i686-mingw32-gcc -O2 -c ../plugin-stub.c
  i686-mingw32-ar cr libplugin-stub.a plugin-stub.o
  i686-mingw32-ranlib libplugin-stub.a
  cd ..

  mkdir -p gcc-build/gcc
  cp libplugin-stub/libplugin-stub.a gcc-build/gcc/
fi

# Build libodb
#
if [ $pack = n ]; then
  make -C `find_out_dir $src_root/odb/libodb` -f $src_root/odb/libodb/makefile \
    dist dist_prefix=$out_root/libodb

  if [ $rebuild = y ]; then
    cd libodb
    ./bootstrap
    cd ..
  fi
else
  libodb=`echo $src_root/pack/libodb-$mver.*.tar.gz | sed -e "s%$src_root/pack/\(.*\)\.tar\.gz%\1%"`
  tar xfz $src_root/pack/$libodb.tar.gz
  mv $libodb libodb
fi

cd libodb

if [ $rebuild = y ]; then
  ../libodb-configure
fi

make
cd odb
make install-data
cd ../..

# Build libodb-boost
#
if [ $pack = n ]; then
  make -C `find_out_dir $src_root/odb/libodb-boost` -f $src_root/odb/libodb-boost/makefile \
    dist dist_prefix=$out_root/libodb-boost

  if [ $rebuild = y ]; then
    cd libodb-boost
    ./bootstrap
    cd ..
  fi
else
  libodb_boost=`echo $src_root/pack/libodb-boost-$mver.*.tar.gz | sed -e "s%$src_root/pack/\(.*\)\.tar\.gz%\1%"`
  tar xfz $src_root/pack/$libodb_boost.tar.gz
  mv $libodb_boost libodb-boost
fi

cd libodb-boost

if [ $rebuild = y ]; then
  ../libodb-boost-configure
fi

make
make install-data
cd ..

# Build libodb-qt
#
if [ $pack = n ]; then
  make -C `find_out_dir $src_root/odb/libodb-qt` -f $src_root/odb/libodb-qt/makefile \
    dist dist_prefix=$out_root/libodb-qt

  if [ $rebuild = y ]; then
    cd libodb-qt
    ./bootstrap
    cd ..
  fi
else
  libodb_qt=`echo $src_root/pack/libodb-qt-$mver.*.tar.gz | sed -e "s%$src_root/pack/\(.*\)\.tar\.gz%\1%"`
  tar xfz $src_root/pack/$libodb_qt.tar.gz
  mv $libodb_qt libodb-qt
fi

cd libodb-qt

if [ $rebuild = y ]; then
  ../libodb-qt-configure
fi

make
make install-data
cd ..

# Build libcutl
#
if [ $pack = n ]; then
  make -C $src_root/cutl/libcutl dist dist_prefix=$out_root/libcutl

  if [ $rebuild = y ]; then
    cd libcutl
    ./bootstrap
    cd ..
  fi
else
  tar xfz $src_root/libcutl-$cver.tar.gz
  mv libcutl-$cver libcutl
fi

cd libcutl

if [ $rebuild = y ]; then
  ../libcutl-configure
fi

make -j 10
cd ..

# Build odb
#
if [ $pack = n ]; then
  make -C $src_root/odb/odb dist dist_prefix=$out_root/odb

  if [ $rebuild = y ]; then
    cd odb
    ./bootstrap
    cd ..
  fi
else
  tar xfz $src_root/pack/odb-$over.tar.gz
  mv odb-$over odb
fi

mkdir -p odb-build
cd odb-build

if [ $rebuild = y ]; then
  ../odb-configure $over
fi

make -j 10
make install-strip
rm -r $install_root/libexec # odb/odb.a
cd ..

# Build gcc
#
mkdir -p gcc-build
cd gcc-build

if [ $rebuild = y ]; then
  ../gcc-configure
else
  rm -f gcc/cc1plus.exe gcc/cc1plus-dummy.exe
fi

make STATIC_PLUGIN_LIBS="-Wl,--whole-archive $out_root/odb-build/odb/.libs/odb.a -Wl,--no-whole-archive $out_root/libcutl/cutl/.libs/libcutl.a -lstdc++ -static-libgcc" -j 10
make install
make -C i686-mingw32/libstdc++-v3 install-strip
cd ..

# Copy /mingw over to installation
#
cp -r /mingw $install_root/

# Move mingw/lib/gcc/i686-mingw32/libgcc_s_dw2-1.dll to mingw/bin/.
#
if [ -e $install_root/mingw/lib/gcc/i686-mingw32/libgcc_s_dw2-1.dll ]; then
  mv $install_root/mingw/lib/gcc/i686-mingw32/libgcc_s_dw2-1.dll $install_root/mingw/bin/
fi

# Move doc and man out of share/
#
rm -rf $install_root/doc $install_root/man
mv $install_root/share/man $install_root/
mv $install_root/share/doc/odb $install_root/doc
rm -r $install_root/share

# Clean some things up.
#
rm -f $install_root/mingw/lib/libbfd.*
rm -f $install_root/mingw/include/bfd*.h
rm -f $install_root/mingw/lib/libopcodes.*
rm -f $install_root/mingw/lib/libiberty.a
rm -f `find $install_root -name '*.la'`

# Copy msys over to installation.
#
cp -r msys/* $install_root/mingw/

# Copy the default options file.
#
mkdir -p $install_root/etc/odb
cp -L default.options $install_root/etc/odb/
todos $install_root/etc/odb/default.options

# Copy manifest.
#
cp -L manifest.txt $install_root/mingw/
todos $install_root/mingw/manifest.txt

# Copy README.
#
cp -L README $install_root/README
todos $install_root/README

# Zip it up.
#
cd /tmp
mkdir -p pack
zip -r pack/odb-$over-i686-windows.zip odb-$over-i686-windows
cd $out_root