#!/bin/bash
[% c("var/set_default_env") -%]
[% pc(c('var/compiler'), 'var/setup', {
        compiler_tarfile => c('input_files_by_name/' _ c('var/compiler')),
        hardened_gcc => 0, # don't set hardened_gcc since firefox is setting the hardened flags
      }) %]
distdir=/var/tmp/dist/[% project %]
mkdir -p /var/tmp/build
[% SET out_dir = dest_dir _ '/' _ c('filename') -%]
mkdir -p [% out_dir %]

[% IF c("var/windows") -%]
  # Setting up fxc2
  tar -C /var/tmp/dist -xf [% c('input_files_by_name/fxc2') %]
  export PATH="/var/tmp/dist/fxc2/bin:$PATH"

  tar -C /var/tmp/dist -xf [% c('input_files_by_name/windows-rs') %]
  export MOZ_WINDOWS_RS_DIR=/var/tmp/dist/windows-rs/
[% END -%]

tar -C /var/tmp/dist -xf [% c('input_files_by_name/rust') %]
tar -C /var/tmp/dist -xf [% c('input_files_by_name/cbindgen') %]
tar -C /var/tmp/dist -xf [% c('input_files_by_name/node') %]
[% IF ! c("var/linux-aarch64") -%]
  tar -C /var/tmp/dist -xf [% c('input_files_by_name/nasm') %]
  export PATH="/var/tmp/dist/nasm/bin:$PATH"
[% END -%]
export PATH="/var/tmp/dist/rust/bin:/var/tmp/dist/cbindgen:/var/tmp/dist/node/bin:$PATH"

[% IF c("var/linux") -%]
  tar -C /var/tmp/dist -xf [% c('input_files_by_name/clang') %]
  tar -C /var/tmp/dist -xf [% c('input_files_by_name/python') %]
  export PATH="/var/tmp/dist/python/bin:$PATH"
  [% IF ! c("var/linux-cross") -%]
    tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/binutils') %]
    export PATH="/var/tmp/dist/binutils/bin:$PATH"
  [% END -%]
  # Use clang for everything on Linux now if we don't build with ASan.
  [% IF ! c("var/asan") -%]
    export PATH="/var/tmp/dist/clang-linux/bin:$PATH"
  [% END -%]
  [% IF c("var/linux-i686") -%]
    # Exporting `PKG_CONFIG_PATH` in the mozconfig file is causing build
    # breakage in Rust code. It seems that environment variable is not passed
    # down properly in that case. Thus, we set it here in the build script.
    export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/lib/i386-linux-gnu/pkgconfig"
  [% ELSIF c("var/linux-cross") -%]
    export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/lib/[% c("var/crosstarget") %]/pkgconfig"
  [% END -%]
[% END -%]

[% IF c("var/rlbox") -%]
  tar -C /var/tmp/dist -xf [% c('input_files_by_name/wasi-sysroot') %]
  export WASI_SYSROOT=/var/tmp/dist/wasi-sysroot
[% END -%]

tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.[% c('compress_tar') %]

mkdir -p $distdir/[% IF ! c("var/macos") %]Browser[% END %]

cd /var/tmp/build/[% project %]-[% c("version") %]
cat > .mozconfig << 'MOZCONFIG_EOF'
[% INCLUDE mozconfig %]
MOZCONFIG_EOF
[% IF c("var/asan") -%]
  # Without disabling LSan our build is blowing up:
  # https://bugs.torproject.org/10599#comment:52
  export ASAN_OPTIONS="detect_leaks=0"
[% END -%]

[% c("var/set_MOZ_BUILD_DATE") %]

[% IF c("var/windows") -%]
  # Make sure widl is not inserting random timestamps, see #21837.
  export WIDL_TIME_OVERRIDE="0"
  patch -p1 < $rootdir/nsis-uninstall.patch
  # mingw-w64 does not support SEH on 32bit systems. Be explicit about that.
  export LDFLAGS="[% c('var/flag_noSEH') %]"
[% END -%]

[% IF c("var/namecoin") -%]
  patch -p1 < $rootdir/namecoin-etld.patch
[% END -%]

[% IF c("var/namecoin") -%]
  pushd toolkit/torbutton
  patch -p1 < $rootdir/namecoin-torbutton.patch
  popd
[% END -%]

[% IF c("var/override_updater_url") -%]
  [% IF c("var/release") || c("var/alpha") -%]
    cp $rootdir/marsigner.der toolkit/mozapps/update/updater/release_secondary.der
  [% ELSIF c("var/nightly") -%]
    cp $rootdir/marsigner.der toolkit/mozapps/update/updater/nightly_aurora_level3_secondary.der
  [% END -%]
[% END -%]

export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system

# Create .mozbuild to avoid interactive prompt in configure
mkdir "$HOME/.mozbuild"

[% INCLUDE 'browser-localization' %]

# PyYAML tries to read files as ASCII, otherwise
export LC_ALL=C.UTF-8
export LANG=C.UTF-8

echo "Starting ./mach configure $(date)"
./mach configure \
  --with-distribution-id=org.torproject \
  --with-base-browser-version=[% c("var/torbrowser_version") %] \
  [% IF c("var/updater_enabled") -%]--enable-update-channel=[% c("var/channel") %][% END %] \
  [% IF !c("var/base-browser") -%]--with-branding="$branding_dir"[% END %] \
  [% IF !c("var/rlbox") -%]--without-wasm-sandboxed-libraries[% END %]

echo "Starting ./mach build $(date)"
./mach build --verbose
[% IF c("var/has_l10n") -%]
  echo "Starting to merge locales $(date)"
  export MOZ_CHROME_MULTILOCALE="$supported_locales"
  # No quotes on purpose, see https://firefox-source-docs.mozilla.org/build/buildsystem/locales.html#instructions-for-multi-locale-builds
  ./mach package-multi-locale --locales en-US $MOZ_CHROME_MULTILOCALE
  AB_CD=multi ./mach build stage-package
  echo "Locales merged $(date)"
[% ELSE -%]
  ./mach build stage-package
[% END -%]

[% IF c("var/macos") -%]
  cp -a obj-*/dist/[% c('var/exe_name') %]/* $distdir
  [% IF c("var/base-browser") -%]
    mv "$distdir/Firefox.app" "$distdir/[% c('var/display_name') %].app"
  [% END -%]
  app_bundle="[% c('var/display_name') %].app"
  # Remove firefox-bin (we don't use it, see ticket #10126)
  rm -f "$distdir/$app_bundle/Contents/MacOS/[% c('var/exe_name') %]-bin"

  # Adjust the Info.plist file
  INFO_PLIST="$distdir/$app_bundle/Contents/Info.plist"
  python3 $rootdir/fix-info-plist.py \
    "$INFO_PLIST" \
    '[% c("var/Project_Name") %]' \
    '[% c("var/torbrowser_version") %]' \
    '[% c("var/copyright_year") %]' \
    [% IF c("var/mullvad-browser") -%]'Mullvad, Tor Browser and Mozilla Developers'[% ELSE -%]'The Tor Project'[% END %]
[% END -%]

[% IF c("var/linux") -%]
  cp -a obj-*/dist/[% c('var/exe_name') %]/* $distdir/Browser/
  mkdir -p $distdir/Debug
  # Some include files are symlinks, so use -Lr, or the tarball will fail
  # silently. Also, on Linux we populate the debug symbols by stripping later.
  cp -Lr obj-*/dist/include $distdir/Debug/
  # Remove firefox-bin (we don't use it, see ticket #10126)
  rm -f "$distdir/Browser/[% c('var/exe_name') %]-bin"
  # TODO: There goes FIPS-140.. We could upload these somewhere unique and
  # subsequent builds could test to see if they've been uploaded before...
  # But let's find out if it actually matters first..
  rm -f $distdir/Browser/*.chk
  # Replace $exe_name by a wrapper script (#25485)
  mv "$distdir/Browser/[% c('var/exe_name') %]" "$distdir/Browser/[% c('var/exe_name') %].real"
  cat > "$distdir/Browser/[% c('var/exe_name') %]" << 'RBM_TB_EOF'
[% INCLUDE 'start-firefox' -%]
RBM_TB_EOF
  chmod 755 "$distdir/Browser/[% c('var/exe_name') %]"
[% END -%]

[% IF c("var/windows") -%]
  cp -a obj-*/dist/[% c('var/exe_name') %]/* $distdir/Browser/
  [% IF c("var/windows-i686") -%]
    cp -a /var/tmp/dist/fxc2/bin/d3dcompiler_47_32.dll $distdir/Browser/d3dcompiler_47.dll
  [% ELSE -%]
    cp -a /var/tmp/dist/fxc2/bin/d3dcompiler_47.dll $distdir/Browser
  [% END -%]
  mkdir -p $distdir/Debug/Browser
  pushd obj-*
  cp -Lr dist/include $distdir/Debug/
  find . -path ./_tests -prune -o -name '*.pdb' -exec cp -l {} $distdir/Debug/Browser/ \;
  popd
[% END -%]

cp -L obj-*/dist/bin/geckodriver* $distdir

[% IF c("var/updater_enabled") -%]
  # Make MAR-based update tools available for use during the bundle phase.
  # Note that mar and mbsdiff are standalone tools, compiled for the build
  # host's architecture.  We also include signmar, certutil, and the libraries
  # they require; these utilities and libraries are built for the target
  # architecture.
  MARTOOLS=$distdir/mar-tools
  mkdir -p $MARTOOLS
  cp -p config/createprecomplete.py $MARTOOLS/
  cp -p tools/update-packaging/*.sh $MARTOOLS/
  cp -p obj-*/dist/host/bin/mar $MARTOOLS/
  cp -p obj-*/dist/host/bin/mbsdiff $MARTOOLS/
  [% IF c("var/linux") || c("var/macos") -%]
    cp -p obj-*/dist/bin/signmar $MARTOOLS/
    cp -p obj-*/dist/bin/certutil $MARTOOLS/
    cp -p obj-*/dist/bin/pk12util $MARTOOLS/
    [% IF c("var/linux") -%]
      NSS_LIBS="libfreeblpriv3.so libmozsqlite3.so libnss3.so libnssckbi.so libnssutil3.so libsmime3.so libsoftokn3.so libssl3.so"
      NSPR_LIBS="libnspr4.so libplc4.so libplds4.so"
    [% ELSE -%]
      NSS_LIBS="libfreebl3.dylib libmozglue.dylib libnss3.dylib libnssckbi.dylib libsoftokn3.dylib"
      # No NSPR_LIBS for macOS
      NSPR_LIBS=""
    [% END -%]
    for LIB in $NSS_LIBS $NSPR_LIBS; do
      cp -p obj-*/dist/bin/$LIB $MARTOOLS/
    done
  [% END -%]
  [% IF c("var/windows") -%]
    cp -p obj-*/dist/bin/signmar.exe $MARTOOLS/
    cp -p obj-*/dist/bin/certutil.exe $MARTOOLS/
    cp -p obj-*/dist/bin/pk12util.exe $MARTOOLS/
    NSS_LIBS="freebl3.dll mozglue.dll nss3.dll nssckbi.dll softokn3.dll"
    for LIB in $NSS_LIBS; do
        cp -p obj-*/dist/bin/$LIB $MARTOOLS/
    done
  [% END -%]
[% END -%]

[% IF c("var/mullvad-browser") && c("var/windows") -%]
  function make_nsis_plugin {
    pushd "other-licenses/nsis/Contrib/$1"
    make CXX=[% c("arch") %]-w64-mingw32-clang++
    cp "$1.dll" $distdir/nsis-plugins/
    [% c("touch") %] "$distdir/nsis-plugins/$1.dll"
    popd
  }

  mkdir -p $distdir/nsis-plugins
  make_nsis_plugin ApplicationID
  make_nsis_plugin CityHash
[% END -%]

cd $distdir

[% IF c("var/linux") -%]
  [% IF c("var/linux-cross") -%]
    CROSS_PREFIX=[% c("var/crosstarget") %]-
  [% END -%]

  OBJCOPY="${CROSS_PREFIX}objcopy"
  STRIP="${CROSS_PREFIX}strip"

  mkdir -p $distdir/Debug/Browser
  # Strip and generate debuginfo for the firefox binary that we keep, all *.so
  # files, and the updater (see ticket #10126)
  for LIB in Browser/*.so "Browser/[% c('var/exe_name') %].real" [% IF c("var/updater_enabled") -%]Browser/updater[% END %]
  do
    "$OBJCOPY" --only-keep-debug $LIB Debug/$LIB
    "$STRIP" $LIB
    "$OBJCOPY" --add-gnu-debuglink=./Debug/$LIB $LIB
  done
[% END -%]

# Re-zipping the omni.ja files is not needed to make them reproductible,
# however if we don't re-zip them, the files become corrupt when we
# update them using 'zip' and firefox will silently fail to load some
# parts.
[% IF c("var/windows") || c("var/linux") -%]
  [% c("var/rezip", { rezip_file => 'Browser/omni.ja' }) %]
  [% c("var/rezip", { rezip_file => 'Browser/browser/omni.ja' }) %]
[% ELSIF c("var/macos") -%]
  [% c("var/rezip", { rezip_file => '"$app_bundle/Contents/Resources/omni.ja"' }) %]
  [% c("var/rezip", { rezip_file => '"$app_bundle/Contents/Resources/browser/omni.ja"' }) %]
[% END -%]

[%
IF c("var/macos");
  SET browserdir='"$app_bundle/Contents"';
ELSE;
  SET browserdir='Browser';
END;
%]

[% IF c("var/linux") -%]
  /var/tmp/dist/gcc/bin/"${CROSS_PREFIX}g++" $rootdir/abicheck.cc -o Browser/abicheck -std=c++17
  libdest=Browser/libstdc++
  mkdir -p "$libdest"
  libdir=[% c("var/libdir") %]
  [% IF c("var/linux-cross") -%]
    libdir="[% c("var/crosstarget") %]/$libdir"
  [% END -%]
  # Not copying libstdc++.so.* as that dups with the full libstdc++.so.6.0.xx the .6 links to
  # and libstdc++.so.6.0.28-gdb.py which is also not needed
  cp "/var/tmp/dist/gcc/$libdir/libstdc++.so.6" "$libdest"
  [% IF c("var/asan") -%]
    cp "/var/tmp/dist/gcc/$libdir/libasan.so."* "$libdest"
    cp "/var/tmp/dist/gcc/$libdir/libubsan.so."* "$libdest"
  [% END -%]
  # Strip and generate debuginfo for libs
  for LIB in "$libdest"/*so*
  do
    "$STRIP" "$LIB"
  done
[% END -%]

echo "Starting to package artifacts $(date)"

[% c('tar', {
        tar_src => [ browserdir ],
        tar_args => '-caf ' _ out_dir _ '/browser.tar.' _ c('compress_tar'),
    }) %]

# Debug symbols
[% IF c("var/linux") -%]
  pushd Debug
  mkdir -p [% c('var/project-name') %]/Browser
  mv Browser [% c('var/project-name') %]/Browser/.debug
  mv include [% c('var/project-name') %]/
  [% c('tar', {
      tar_src => [ c('var/project-name') ],
      tar_args => '-cJf ' _ out_dir _ '/browser-debug-symbols.tar.xz',
    }) %]
  popd
[% ELSIF c("var/windows") -%]
  [% c('zip', {
      zip_src => [ 'Debug' ],
      zip_args => out_dir _ '/browser-debug-symbols.zip',
    }) %]
[% END -%]

# Geckodriver
llvm-strip geckodriver*
[% IF c("var/windows") -%]
  [% c('zip', {
      zip_src => [ 'geckodriver.exe' ],
      zip_args => out_dir _ '/geckodriver.zip',
    }) %]
[% ELSE -%]
  [% c('tar', {
      tar_src => [ 'geckodriver' ],
      tar_args => '-cJf ' _ out_dir _ '/geckodriver.tar.xz',
    }) %]
[% END -%]

# MAR tools
[% IF c("var/updater_enabled") -%]
  [% c('zip', {
      zip_src => [ 'mar-tools' ],
      zip_args => out_dir _ '/' _ 'mar-tools-' _ c("var/osname") _ '-' _ c("var/torbrowser_version") _ '.zip',
    }) %]
[% END -%]

[% IF c("var/mullvad-browser") && c("var/windows") -%]
  [% c('tar', {
      tar_src => [ 'nsis-plugins' ],
      tar_args => '-caf ' _ out_dir _ '/nsis-plugins.tar.' _ c('compress_tar'),
    }) %]
[% END -%]

[% IF c("var/build_infos_json") -%]
  cat > "[% out_dir _ '/build-infos.json' %]" << EOF_BUILDINFOS
  {
      "firefox_platform_version" : "[% c("var/firefox_platform_version") %]",
      "firefox_buildid" : "$MOZ_BUILD_DATE"
  }
EOF_BUILDINFOS
[% END -%]
