#!/usr/bin/env bash

_thisdir="$(dirname $0)"
test "${_thisdir}" = "." && _thisdir=${PWD}
_ifwroot="${_thisdir}"/qt-ifw
_arch=$(uname -m)
_date=$(date +'%Y%m%d')
_dateqif=$(date +'%Y-%m-%d')
_version=${_date}
_filename=msys2-${_arch}-${_date}.exe
_filename2=msys2-base-${_arch}-${_date}.tar.xz
_log=/tmp/installer-${_arch}-${_date}.log
if [ "${_arch}" = "x86_64" ]; then
  _bitness=64
else
  _bitness=32
fi
_archivegen=/mingw${_bitness}/bin/archivegen.exe
_binarycreator=/mingw${_bitness}/bin/binarycreator.exe
_installerbase=/mingw${_bitness}/bin/installerbase.exe
_newmsysbase=/tmp/newmsys
_newmsys=${_newmsysbase}/msys"${_bitness}"

declare -a undo_commands

_exitcode=5

exit_with_undo() {
  for _cmd in ${undo_commands[@]}; do
    eval "${_cmd}" | tee -a ${_log}
  done
  exit ${_exitcode}
}

exit_cleanly() {
  _exitcode=$1; shift;
  local _message=$1; shift;
  echo "${_message}" | tee -a ${_log}
  exit_with_undo
}

do_seds() {
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|@DATE@|${_dateqif}|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|@VERSION@|${_version}|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" -or -name "installscript.js" \) -exec sed -i "s|@BITNESS@|${_bitness}|g" "{}" \;
  undo_commands+=("undo_seds")
}

undo_seds() {
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|<ReleaseDate>${_dateqif}<|<ReleaseDate>@DATE@<|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|<Version>${_version}<|<Version>@VERSION@<|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" -or -name "installscript.js" \) -exec sed -i "s|msys${_bitness}|msys@BITNESS@|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" -or -name "installscript.js" \) -exec sed -i "s|${_bitness}bit|@BITNESS@bit|g" "{}" \;
}

create_archives() {
  local _data="${_ifwroot}"/packages/com.msys2.root.base/data
  [ -d "${_data}" ] && rm -rf "${_data}"
  mkdir -p "${_data}"
  local _dirs=
  for curr_dir in /etc /var /tmp /usr /mingw32_shell.bat /mingw64_shell.bat /msys2_shell.bat /msys2.ico /autorebase.bat autorebasebase1st.bat; do
    if [[ -d ${_newmsys}${curr_dir} || -f ${_newmsys}${curr_dir} ]]; then
      _dirs="${_dirs} ${_newmsys}$curr_dir"
    fi
  done

  if [ -n "${_dirs}" ]; then
    local _compress_cmd="${_archivegen} ${_data}/msys${_bitness}.7z ${_dirs}"
    pushd / > /dev/null
      echo "Run: ${_compress_cmd} ..." | tee -a ${_log}
      eval "${_compress_cmd}" 2>&1 | tee -a ${_log}
      _result=$?
      if [ "${_result}" -eq "0" ]; then
            echo " archivegen succeeded. Created ${_data}/msys${_bitness}.7z" | tee -a ${_log}
      else
            exit_cleanly "3" "archivegen failed. See ${_log}"
      fi
    popd > /dev/null

    pushd ${_newmsysbase} > /dev/null
      local _compress_cmd2="/usr/bin/tar --transform='s/:/_/g' --dereference --hard-dereference -cJf ${_thisdir}/${_filename2} msys${_bitness}"
      echo "Run: ${_compress_cmd2} ..." | tee -a ${_log}
      eval "${_compress_cmd2}" 2>&1 | tee -a ${_log}
      _result=$?
      if [ "${_result}" -eq "0" ]; then
            echo " tar succeeded. Created " | tee -a ${_log}
      else
            die "MSYS2 compressing fail. See ${_log}"
      fi
    popd > /dev/null
  fi
}

# Add -v to get more information.
make_installer() {
  eval "\"${_binarycreator}\" \
    -t \"${_installerbase}\" \
    -p \"${_ifwroot}/packages\" \
    -c \"${_ifwroot}/config/config.xml\" \
    --offline-only \
    \"${_filename}\" \
    -v"  | tee -a ${_log}
}

trap exit_with_undo 1 2 15

create_chroot_system() {
  [ -d ${_newmsysbase} ] && rm -rf ${_newmsysbase}
  mkdir -p "${_newmsys}"
  pushd "${_newmsys}" > /dev/null

    mkdir -p var/lib/pacman
    mkdir -p var/log
    mkdir -p tmp

    eval "pacman -Syu --root \"${_newmsys}\"" | tee -a ${_log}
    eval "pacman -S base --noconfirm --root \"${_newmsys}\"" | tee -a ${_log}
    _result=$?
    if [ "${_result}" -ne "0" ]; then
      exit_cleanly "1" "failed to create newmsys2 via command 'pacman -S base --noconfirm --root ${_newmsys}'"
    fi
  popd > /dev/null
}

if [ ! -f "${_archivegen}" ]; then
  eval "pacman -S --noconfirm mingw${_bitness}/mingw-w64-${_arch}-qt-installer-framework-git" | tee -a ${_log}
fi

if [ ! -f "${_archivegen}" ]; then
  exit_cleanly "2" "installation of qt installer framework failed. See ${_log}"
fi

if [ -f "${_log}" ]; then
  rm "${_log}"
fi

echo "Creating MSYS2 chroot system ${_newmsys}" | tee -a ${_log}
create_chroot_system

echo "Creating MSYS2 installer /tmp/${_filename}" | tee -a ${_log}
if [ -f /tmp/${_filename} ]; then
  rm -f /tmp/${_filename}
fi

do_seds
create_archives
make_installer
exit_cleanly "0" "All done, see ${_filename}"
