#!/bin/bash
### usage: build-windows [opts..]
###
### Cross compiles the Windows distribution from a Linux host

set -euo pipefail
cd "$(dirname "$0")/.."
source script/lib/functions.sh
source script/lib/error.sh

# configure me!
PROFILE=release
TARGET=x86_64-pc-windows-msvc
ARCH=x86_64

# check for WINDOWS_KITS
[ -n "${WINDOWS_KITS:-}" ] || die "WINDOWS_KITS not set, cannot proceed. Hailey will document this whole thing eventually"

# check for prerequisite commands
check-command lld-link
check-command wine
check-command winepath

# check for gtk installation - build this on Windows with gvsbuild
GTK_KIT="$WINDOWS_KITS/gtk"
[ -d "$GTK_KIT" ] || die "cannot find gtk kit in $GTK_KIT"

# check for windows sdk - grab this with xwin
XWIN_KIT="$WINDOWS_KITS/xwin"
[ -d "$XWIN_KIT" ] || die "cannot find xwin kit in $XWIN_KIT"

# grab version number from git
version="$(git describe --tags)"
info "Version $version"

# pass --release to cargo if PROFILE==release:
cargo_args=()
[[ "$PROFILE" == "release" ]] && cargo_args+="--release"

# set env vars we need for cross compilation
cl_flags=(
    -msse2
    -fms-compatibility
    -fuse-ld=lld-link
    "-I$XWIN_KIT/crt/include"
    "-I$XWIN_KIT/sdk/include/ucrt"
    "-I$XWIN_KIT/sdk/include/um"
    "-I$XWIN_KIT/sdk/include/shared"
)

rustflags=(
    -C link-arg=/STACK:8000000
    -C "link-arg=/LIBPATH:$GTK_KIT/$ARCH/lib"
    "-Lnative=$XWIN_KIT/crt/lib/$ARCH"
    "-Lnative=$XWIN_KIT/sdk/lib/ucrt/$ARCH"
    "-Lnative=$XWIN_KIT/sdk/lib/um/$ARCH"
)

export PKG_CONFIG_ALLOW_CROSS=1
export PKG_CONFIG_ALLOW_SYSTEM_LIBS=0
export PKG_CONFIG_LIBDIR="$GTK_KIT/$ARCH/lib/pkgconfig"

export CC_x86_64_pc_windows_msvc=clang-cl
export AR_x86_64_pc_windows_msvc=llvm-lib
export CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER=lld-link

# using a * array expansion rather than @ defeats the purpose of quoting the
# array elements above properly :'( but these vars are just strings anyway so
# not much we can do about it
export CL_FLAGS="${cl_flags[*]}"
export CFLAGS_x86_64_pc_windows_msvc="$CL_FLAGS"
export RUSTFLAGS="${rustflags[*]}"

# do the build
info "Compiling"
log-command cargo build --target="$TARGET" "${cargo_args[@]}" --all

# build the installer
info "Building installer"

dist_dir="dist/$version"
mkdir -p "$dist_dir"

# convert unix paths to windows paths
# winepath starts quite slowly so batch all the paths up into one call
win_pwd="$(winepath --windows "$PWD" 2>/dev/null)"
win_gtk="$(winepath --windows "$GTK_KIT/$ARCH" 2>/dev/null)"
setup_exe_basename="tangaracompanion-$version-windows-$ARCH"
cli_exe_basename="tangara-cli-$version-windows-$ARCH"

: "${WINE_PREFIX:="$HOME/.wine"}"
wine "$WINE_PREFIX/drive_c/Program Files (x86)/Inno Setup 6/ISCC.exe" \
    /Q /Qp \
    "/DProjectDir=$win_pwd" \
    "/DGtkDir=$win_gtk" \
    "/DCargoTargetDir=$win_pwd\\target\\$TARGET\\$PROFILE" \
    "/DDistDir=$win_pwd\\dist\\$version" \
    "/DAppVersion=$version" \
    "/DSetupExeName=$setup_exe_basename" \
    pkg/windows/installer.iss

cp "$PWD/target/$TARGET/$PROFILE/tangara.exe" "$dist_dir/$cli_exe_basename.exe"

win "windows installer written to $dist_dir/$setup_exe_basename.exe"
win "windows cli written to $dist_dir/$cli_exe_basename.exe"
