#!/usr/bin/env bash

# Exit on error
set -e

# Number of parallel jobs
jobs=$(nproc)

if [ -z "$AppImageArch" ]; then
  AppImageArch=x86_64
fi

# Set environment variables
export OS=`uname`

if [ "$AppImageArch" = i686 ]; then
  export HOST=i386-linux-gnu
  export BUILD_X86=True
elif [ "$AppImageArch" = x86_64 ]; then
  export HOST=x86_64-linux-gnu
elif [ "$AppImageArch" = armhf ]; then
  export HOST=arm-linux-gnueabihf
elif [ "$AppImageArch" = aarch64 ]; then
  export HOST=aarch64-linux-gnu
elif [ "$AppImageArch" = riscv64 ]; then
  export HOST=riscv64-linux-gnu
elif [ "$AppImageArch" = ppc64el ]; then
  export HOST=powerpc64le-linux-gnu
fi

# Make tool
if [[ "$OS" = Linux ]]; then
  export MAKE=make
else
  export MAKE=gmake
fi

# Build libcdio
./tools/build-codecs libcdio libcdio-paranoia

# Build libcurl
wget -c https://curl.se/download/curl-8.11.0.tar.bz2
tar xfj curl-8.11.0.tar.bz2
cd curl-8.11.0

if [ $AppImageArch = i686 ]; then
  CFLAGS="-m32" ./configure --disable-docs --with-ssl --without-librtmp --without-libpsl --disable-ldap --without-zstd --without-brotli --without-nghttp2 --without-libidn2
else
  ./configure --host=$HOST --disable-docs --with-ssl --without-librtmp --without-libpsl --disable-ldap --without-zstd --without-brotli --without-nghttp2 --without-libidn2
fi

$MAKE -j$jobs
sudo $MAKE install

if [ "$OS" = Linux ]; then
  sudo rm /usr/local/bin/curl
fi

cd ..

# Build smooth
cd smooth

CONFIG="release,bundledlibbz2,bundledlibfribidi,bundledlibjpeg,bundledlibpng,bundledlibxml2,bundledzlib"

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/$HOST/pkgconfig

$MAKE config=$CONFIG -j$jobs
sudo $MAKE config=$CONFIG install

unset PKG_CONFIG_PATH

cd ..

# Build BoCA
cd boca

CONFIG="release,bundledlibexpat,bundledliburiparser,bundledzlib"

$MAKE config=$CONFIG -j$jobs

if [ "$AppImageArch" = i686 ]; then
  sudo $MAKE BUILD_X86=True config=$CONFIG install
else
  sudo $MAKE config=$CONFIG install
fi

if [ "$AppImageArch" = x86_64 ]; then
  # Install 32 bit Wine build tools
  if [ "$OS" = Linux ]; then
    sudo apt install -y wine32-tools
  else
    /usr/local/share/wine/pkg32.sh install -y wine
  fi

  # Build 32 bit Core Audio connector
  cd components/encoder/coreaudioconnect/connector

  $MAKE BUILD_X86=True config=$CONFIG clean
  $MAKE BUILD_X86=True config=$CONFIG -j$jobs
  sudo $MAKE BUILD_X86=True config=$CONFIG install

  cd ../../../..
fi

cd ..

# Build fre:ac
CONFIG="release"

$MAKE config=$CONFIG -j$jobs
sudo $MAKE config=$CONFIG install

# Build codecs and DSP libraries
cd tools

./build-codecs faad2 fdk-aac mp4v2
./build-codecs lame mpg123
./build-codecs libogg opus speex vorbis
./build-codecs flac mac musepack wavpack
./build-codecs ffmpeg libsndfile
./build-codecs libsamplerate rnnoise rubberband

cd ..

# Install codecs
mkdir -p appdir/codecs

cp /usr/local/lib/libFLAC.so appdir/codecs/FLAC.so
cp /usr/local/lib/libMAC.so appdir/codecs/MAC.so
cp /usr/local/lib/libfaad.so appdir/codecs/faad.so
cp /usr/local/lib/libfdk-aac.so appdir/codecs/fdk-aac.so
cp /usr/local/lib/libmp3lame.so appdir/codecs/mp3lame.so
cp /usr/local/lib/libmp4v2.so appdir/codecs/mp4v2.so
cp /usr/local/lib/libmpg123.so appdir/codecs/mpg123.so
cp /usr/local/lib/libogg.so appdir/codecs/ogg.so
cp /usr/local/lib/libopus.so appdir/codecs/opus.so
cp /usr/local/lib/librnnoise.so appdir/codecs/rnnoise.so
cp /usr/local/lib/librubberband.so appdir/codecs/rubberband.so
cp /usr/local/lib/libsamplerate.so appdir/codecs/samplerate.so
cp /usr/local/lib/libsndfile.so appdir/codecs/sndfile.so
cp /usr/local/lib/libspeex.so appdir/codecs/speex.so
cp /usr/local/lib/libvorbis.so appdir/codecs/vorbis.so
cp /usr/local/lib/libvorbisenc.so appdir/codecs/vorbisenc.so

strip --strip-all appdir/codecs/*.so

mkdir -p appdir/codecs/cmdline

install -m 0755 /usr/local/bin/ffmpeg appdir/codecs/cmdline/ffmpeg
install -m 0755 /usr/local/bin/mpcdec appdir/codecs/cmdline/mpcdec
install -m 0755 /usr/local/bin/mpcenc appdir/codecs/cmdline/mpcenc
install -m 0755 /usr/local/bin/wavpack appdir/codecs/cmdline/wavpack
install -m 0755 /usr/local/bin/wvunpack appdir/codecs/cmdline/wvunpack

strip --strip-all appdir/codecs/cmdline/*

# Copy icons
mkdir -p appdir/icons/gnome/32x32/status

if [[ "$OS" = Linux ]]; then
  cp /usr/share/icons/gnome/32x32/status/dialog-error.png appdir/icons/gnome/32x32/status
  cp /usr/share/icons/gnome/32x32/status/dialog-information.png appdir/icons/gnome/32x32/status
  cp /usr/share/icons/gnome/32x32/status/dialog-question.png appdir/icons/gnome/32x32/status
  cp /usr/share/icons/gnome/32x32/status/dialog-warning.png appdir/icons/gnome/32x32/status
else
  cp /usr/local/share/icons/gnome/32x32/status/dialog-error.png appdir/icons/gnome/32x32/status
  cp /usr/local/share/icons/gnome/32x32/status/dialog-information.png appdir/icons/gnome/32x32/status
  cp /usr/local/share/icons/gnome/32x32/status/dialog-question.png appdir/icons/gnome/32x32/status
  cp /usr/local/share/icons/gnome/32x32/status/dialog-warning.png appdir/icons/gnome/32x32/status
fi

# Copy smooth
cp /usr/local/lib/libsmooth*.so.? appdir

# Copy BoCA
cp -r /usr/local/lib/boca appdir
cp /usr/local/lib/libboca-1.0.so.3 appdir/libboca-1.0.so.3

# Copy fre:ac
cp COPYING Readme* appdir
rm appdir/Readme.md

cp -r /usr/local/lib/freac/* appdir/boca
cp -r /usr/local/share/freac/lang appdir
cp -r /usr/local/share/freac/icons appdir
cp -r /usr/local/share/doc/freac/manual appdir

cp /usr/local/lib/libfreac-1.1.so.0 appdir/libfreac-1.1.so.0

install -m 0755 /usr/local/bin/freac appdir/freac
install -m 0755 /usr/local/bin/freaccmd appdir/freaccmd
install -m 0755 /usr/local/bin/smooth-translator appdir/translator
install -m 0755 packaging/appimage/AppRun appdir/AppRun

mkdir -p appdir/usr/share/applications
mkdir -p appdir/usr/share/metainfo

cp /usr/local/share/applications/org.freac.freac.desktop appdir/usr/share/applications
cp /usr/local/share/metainfo/org.freac.freac.appdata.xml appdir/usr/share/metainfo
ln -s usr/share/applications/org.freac.freac.desktop appdir/org.freac.freac.desktop
cp /usr/local/share/icons/hicolor/128x128/apps/org.freac.freac.png appdir

# Copy other dependencies
cp /usr/local/lib/libcdio.so.19 appdir
cp /usr/local/lib/libcdio_cdda.so.2 appdir
cp /usr/local/lib/libcdio_paranoia.so.2 appdir
cp /usr/local/lib/libcurl.so.4 appdir

strip --strip-all appdir/lib*.so*

# Copy OpenSSL dependencies
mkdir -p appdir/openssl

if [[ "$OS" = Linux ]]; then
  cp -P /usr/lib/$HOST/libcrypto.so.3 appdir/openssl
  cp -P /usr/lib/$HOST/libssl.so.3 appdir/openssl
else
  cp -P /lib/libcrypto.so.* appdir/openssl
  cp -P /usr/lib/libssl.so.* appdir/openssl

  chmod 0755 appdir/openssl/libcrypto.so.*
  chmod 0755 appdir/openssl/libssl.so.*
fi

strip --strip-all appdir/openssl/lib*.so*

# Build custom AppImage runtime
if [[ "$AppImageArch" = riscv64 || "$AppImageArch" = ppc64el || "$OS" != Linux ]]; then
  # Check out AppImage runtime
  git clone https://github.com/AppImage/type2-runtime.git
  cd type2-runtime
  git reset --hard 5e7217b
  cd ..

  # Build custom libfuse3
  if [[ "$OS" = Linux ]]; then
    git clone --depth=1 --branch=fuse-3.16.2 https://github.com/libfuse/libfuse.git
  else
    git clone --depth=1 --branch=fuse-3.17.2 https://github.com/libfuse/libfuse.git
  fi
  cd libfuse
  if [[ "$OS" = Linux ]]; then
    patch -p1 < ../type2-runtime/patches/libfuse/mount.c.diff
  fi
  mkdir build
  cd build
  meson setup -D default_library=both ..
  ninja && sudo ninja install
  cd ../..

  # Build libsquashfuse
  git clone --depth=1 --branch=0.5.2 https://github.com/vasi/squashfuse.git
  cd squashfuse
  export pkgconfig_fuse3_CFLAGS="-I/usr/local/include/fuse3"
  export pkgconfig_fuse3_LIBS="-L/usr/local/lib/$HOST -lfuse3 -lpthread"
  autoreconf -i
  ./configure
  make && sudo make install
  sudo cp fuseprivate.h /usr/local/include/squashfuse
  cd ..

  # Build AppImage runtime
  cd type2-runtime
  if [[ "$OS" = Linux ]]; then
    patch -p1 < ../.github/workflows/patches/appimage-type2-runtime-build.patch
  else
    patch -p1 < ../.github/workflows/patches/appimage-type2-runtime-build-freebsd.patch
  fi
  cd src/runtime
  $MAKE
  cd ../../..
fi

# Build custom appimagetool
if [[ "$OS" != Linux ]]; then
  # Build appimagetool
  git clone --branch=1.9.1 --depth=1 https://github.com/AppImage/appimagetool.git
  cd appimagetool
  mkdir build
  cd build
  cmake ..
  make && sudo make install
  cd ../..
fi

# Create AppImage using appimagetool
if [[ "$OS" = Linux ]]; then
  wget -c -nv "https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-x86_64.AppImage"
  chmod a+x appimagetool-x86_64.AppImage

  if [[ "$AppImageArch" = riscv64 || "$AppImageArch" = ppc64el ]]; then
    ./appimagetool-x86_64.AppImage --appimage-extract
    ARCH=x86_64 ./squashfs-root/AppRun --runtime-file=type2-runtime/src/runtime/runtime appdir freac-continuous-${OS,,}-$AppImageArch.AppImage
  else
    ARCH=$AppImageArch ./appimagetool-x86_64.AppImage appdir freac-continuous-${OS,,}-$AppImageArch.AppImage
  fi
else
  ARCH=$AppImageArch appimagetool --runtime-file=type2-runtime/src/runtime/runtime appdir freac-continuous-${OS,,}-$AppImageArch.AppImage
fi

# Upload AppImage to GitHub
bash .github/workflows/tools/upload-build freac*.AppImage
