#!/bin/bash
[% c("var/set_default_env") -%]
distdir=/var/tmp/dist/[% project %]
export TORBROWSER_VERSION='[% c("version") %]'

mkdir -p $distdir

scripts_dir=/var/tmp/build_scripts
mkdir -p "$scripts_dir"

OUTDIR='[% dest_dir _ "/" _ c("filename") %]'
mkdir -p $OUTDIR

# When we build with MULTI_LINGUAL=1, the browser will be packaged inside a
# directory named tor-browser (instead of tor-browser_en-US). Therefore we
# stage everything under tor-browser-stage to avoid a conflict.
TB_STAGE_DIR=$distdir/tor-browser-stage
GENERATEDPREFSPATH=$rootdir/Bundle-Data/generated-prefs.js
# Create initially empty prefs file where we can dump our conditionally included/genetered prefs
touch "$GENERATEDPREFSPATH"

[% IF c("var/macos") %]
  TBDIR="$TB_STAGE_DIR/[% c("var/Project_Name") %].app"
  [% IF c("var/macos_universal") %]
    TBDIR_AARCH64="$TB_STAGE_DIR/[% c("var/Project_Name") %]-aarch64.app"
    TBDIRS=("$TBDIR" "$TBDIR_AARCH64")
  [% ELSE -%]
    TBDIRS=("$TBDIR")
  [% END -%]

  DOCSPATH=Contents/Resources/[% c('var/ProjectName') %]/Docs
  EXTSPATH=Contents/Resources/distribution/extensions
  TORBINPATH=Contents/MacOS/Tor
  TORCONFIGPATH=Contents/Resources/TorBrowser/Tor

  tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/hfsplus-tools') %]
  tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/libdmg') %]
  export PATH=/var/tmp/dist/hfsplus-tools:/var/tmp/dist/libdmg-hfsplus:$PATH
[% ELSE %]
  TBDIR=$TB_STAGE_DIR/Browser
  TBDIRS=("$TBDIR")

  DOCSPATH=[% c('var/ProjectName') %]/Docs
  EXTSPATH=distribution/extensions
  TORBINPATH=TorBrowser/Tor
  TORCONFIGPATH=TorBrowser/Data/Tor

  [% IF c("var/tor-browser") -%]
    PROFILEPATH=[% c('var/ProjectName') %]/Data/Browser/profile.default/extensions
    mkdir -p "$TBDIR/$PROFILEPATH"
  [% END -%]
  [% IF !c("var/mullvad-browser") -%]
    # For Mullvad Browser, we keep the data directory at the same level of
    # Browser, instead of creating a Data directory with the program files.
    mkdir -p "$TBDIR/[% c('var/ProjectName') %]/Data/Browser/Caches"
  [% END -%]
[% END %]

for tbdir in "${TBDIRS[@]}"
do
  mkdir -p "$tbdir/$EXTSPATH"
done

[% IF c("var/updater_enabled") -%]
  # Extract the MAR tools.
  unzip -d $rootdir $rootdir/[% c('input_files_by_name/firefox') %]/mar-tools-*.zip
  MARTOOLS=$rootdir/mar-tools
[% END -%]

mv [% c('input_files_by_name/noscript') %] "$TBDIR/$EXTSPATH/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi"
[% IF c("var/mullvad-browser") -%]
  mv [% c('input_files_by_name/ublock-origin') %] "$TBDIR/$EXTSPATH/uBlock0@raymondhill.net.xpi"
  mv [% c('input_files_by_name/mullvad-extension') %] "$TBDIR/$EXTSPATH/{d19a89b9-76c1-4a61-bcd4-49e8de916403}.xpi"
[% END -%]
[% IF !c("var/macos") && c("var/tor-browser") -%]
  cp "$TBDIR/$EXTSPATH/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi" "$TBDIR/$PROFILEPATH/"
[% END %]

[% IF c("var/tor-browser") -%]
  function mv_tbdir {
    declare args=($@)
    local dest="${args[-1]}"
    unset args[-1]
    mv ${args[@]} "$TBDIR/$dest"
    [% IF c("var/macos_universal") -%]
      for src in ${args[@]}
      do
        mv "aarch64/$src" "$TBDIR_AARCH64/$dest"
      done
    [% END -%]
  }

  tar -xvf [% c('input_files_by_name/tor-expert-bundle') %]
  [% IF c("var/macos_universal") -%]
    mkdir aarch64
    tar -C aarch64 -xf [% c('input_files_by_name/tor-expert-bundle-aarch64') %]
  [% END -%]

  # geoip(6) and anything else that belongs in the data dir from the expert bundle
  mkdir -p "$TBDIR/$TORCONFIGPATH" [% IF c("var/macos_universal") %]"$TBDIR_AARCH64/$TORCONFIGPATH"[% END %]
  mv_tbdir data/{geoip,geoip6} "$TORCONFIGPATH"

  # pt_config.json will be consumed later in `bridges_conf`
  mv tor/pluggable_transports/pt_config.json $rootdir
  [% IF c("var/macos_universal") %]
    rm -f aarch64/tor/pluggable_transports/pt_config.json
  [% END -%]

  # Move READMEs from tor-expert-bundle to the doc dir
  mkdir -p "$TBDIR/$DOCSPATH/snowflake" [% IF c("var/macos_universal") %]"$TBDIR_AARCH64/$DOCSPATH/snowflake"[% END %]

  mkdir -p "$TBDIR/$DOCSPATH/webtunnel" [% IF c("var/macos_universal") %]"$TBDIR_AARCH64/$DOCSPATH/webtunnel"[% END %]
  mkdir -p "$TBDIR/$DOCSPATH/conjure" [% IF c("var/macos_universal") %]"$TBDIR_AARCH64/$DOCSPATH/conjure"[% END %]
  mv_tbdir tor/pluggable_transports/README.SNOWFLAKE.md "$DOCSPATH/snowflake/README.md"
  mv_tbdir tor/pluggable_transports/README.WEBTUNNEL.md "$DOCSPATH/webtunnel/README.md"
  mv_tbdir tor/pluggable_transports/README.CONJURE.md "$DOCSPATH/conjure/README.md"

  # Move the PTs to where TB expects them
  mkdir -p "$TBDIR/$TORBINPATH" [% IF c("var/macos_universal") %]"$TBDIR_AARCH64/$TORBINPATH"[% END %]
  mv_tbdir tor/pluggable_transports "$TORBINPATH/PluggableTransports"

  # Move tor and dependencies to where TB expects them
  mv_tbdir tor/* "$TORBINPATH"

  # on linux, libstdc++ lives in it's own directory
  [% IF c("var/linux") %]
    find $TBDIR/$TORBINPATH
    mkdir -p "$TBDIR/$TORBINPATH/libstdc++"
    mv "$TBDIR/$TORBINPATH"/libstdc++.so.* "$TBDIR/$TORBINPATH/libstdc++"
  [% END %]

  # the expert bundle includes tor-gencert, which isn't needed for browser releases
  [% IF c("var/windows") %]
    rm "$TBDIR/$TORBINPATH/tor-gencert.exe"
  [% END %]

[% END -%]

for tbdir in "${TBDIRS[@]}"
do
  [% IF c("var/macos") -%]
    tbdir="$tbdir/Contents/Resources"
  [% END -%]
  tar -C "$tbdir" -xf [% c('input_files_by_name/fonts') %]
done

[% IF c("var/linux") %]
  cat > ${TB_STAGE_DIR}/start-[% c("var/project-name") %].desktop << 'RBM_TB_EOF'
[% INCLUDE 'RelativeLink/start-browser.desktop' -%]
RBM_TB_EOF
  cat > ${TB_STAGE_DIR}/Browser/start-[% c("var/project-name") %] << 'RBM_TB_EOF'
[% INCLUDE 'RelativeLink/start-browser' -%]
RBM_TB_EOF
  cat > ${TB_STAGE_DIR}/Browser/execdesktop << 'RBM_TB_EOF'
[% INCLUDE 'RelativeLink/execdesktop' -%]
RBM_TB_EOF
  chmod +x ${TB_STAGE_DIR}/start-[% c("var/project-name") %].desktop \
           ${TB_STAGE_DIR}/Browser/start-[% c("var/project-name") %] \
           ${TB_STAGE_DIR}/Browser/execdesktop
  cp ${TB_STAGE_DIR}/start-[% c("var/project-name") %].desktop \
     ${TB_STAGE_DIR}/Browser
  [% IF c("var/namecoin") %]
    pushd ${TB_STAGE_DIR}/Browser/
    patch -p1 < $rootdir/namecoin.patch
    popd
  [% END %]
  # Make sure we get the desired scrollbar behavior with Gtk3, see bug 27546.
  GTK_SETTINGS_DIR=${TB_STAGE_DIR}/Browser/.config/gtk-3.0
  mkdir -p $GTK_SETTINGS_DIR
  cp $rootdir/gtk3-settings.ini $GTK_SETTINGS_DIR/settings.ini
[% END %]

tar -C ${TB_STAGE_DIR} -xf [% c('input_files_by_name/firefox') %]/browser.tar.[% c("compress_tar") %]

[% IF c("var/macos_universal") -%]
  # Use symlink in tmp dir to extract "Tor Browser.app" to "Tor Browser-aarch64.app"
  ff_aarch64=$(mktemp -d)
  ln -s "$TBDIR_AARCH64" "$ff_aarch64/[% c("var/Project_Name") %].app"
  tar -C $ff_aarch64 -xf [% c('input_files_by_name/firefox-aarch64') %]/browser.tar.[% c("compress_tar") %]
[% END %]

[% IF c("var/tor-browser") -%]
  # Include the Tor Browser manual
  TMP_MANUAL_PATH=$rootdir/tmp_manual/
  mkdir $TMP_MANUAL_PATH
  pushd $TMP_MANUAL_PATH
  tar -xf $rootdir/[% c('input_files_by_name/manual') %]
  find . -exec [% c("touch") %] {} \;
  for tbdir in "${TBDIRS[@]}"
  do
    find chrome/ | sort | zip -X -@ "$tbdir[% IF c('var/macos') %]/Contents/Resources[% END %]/browser/omni.ja"
  done
  popd
  rm -rf $TMP_MANUAL_PATH
[% END -%]

[% IF c("var/namecoin") %]
  # Extract Electrum-NMC
  tar -C "$TBDIR/TorBrowser" -xf [% c('input_files_by_name/electrum-nmc') %]

  # Extract ncprop279
  mkdir "$TBDIR/TorBrowser/ncprop279"
  tar -C "$TBDIR/TorBrowser/ncprop279" -xf [% c('input_files_by_name/ncprop279') %]

  # Extract StemNS
  tar -C "$TBDIR/TorBrowser" -xf [% c('input_files_by_name/stemns') %]
[% END %]

[% IF c("var/linux");
     SET bundledata_osname = 'linux';
   ELSIF c("var/macos");
     SET bundledata_osname = 'mac';
   ELSIF c("var/windows");
     SET bundledata_osname = 'windows';
   END; %]

[% IF c("var/macos") %]
  tar -C "Bundle-Data/[% c('var/ProjectName') %].dmg" -c . | tar -C $TB_STAGE_DIR -x
[% END %]

for tbdir in "${TBDIRS[@]}"
do
  [% IF c("var/linux") -%]
    mv Bundle-Data/linux/Data/fontconfig "$tbdir/"
    [% IF c("var/tor-browser") -%]
      # tor-browser#41776: We cannot remove the old fontconfig file with the
      # updater. So, let's keep it for the mar generation, but remove it from
      # new packages.
      # Remove once we do a watershed release.
      oldfontconfig="$tbdir/TorBrowser/Data/fontconfig"
      mkdir -p $oldfontconfig
      cp "$tbdir/fontconfig/fonts.conf" "$oldfontconfig/"
    [% END -%]
  [% END -%]

  mkdir -p "$tbdir/$DOCSPATH"
  cp -a Bundle-Data/Docs/* "$tbdir/$DOCSPATH"
  [% IF c("var/tor-browser") -%]
    cp -a Bundle-Data/Docs-TBB/* "$tbdir/$DOCSPATH"
    tar -C Bundle-Data/[% bundledata_osname %] \
      [% IF ! c("var/namecoin") %]--exclude=*Electrum-NMC* --exclude=*ncprop279*[% END %] \
      -c . | tar -C "$tbdir[% IF ! c("var/macos") %]/[% c('var/ProjectName') %][% END %]" -x
  [% ELSIF c("var/mullvad-browser") -%]
    cp -a Bundle-Data/Docs-MB/* "$tbdir/$DOCSPATH"
  [% END -%]
done

[% IF c("var/tor-browser") -%]
  PT_CONFIG="$rootdir/pt_config.json"

  # Write our ClientTransportPlugin lines to torrc-defults
  for tbdir in "${TBDIRS[@]}"
  do
    PT_PATH='[% c("var/pt_path") %]'
    TORRC_DEFAULTS="$tbdir/$TORCONFIGPATH/torrc-defaults"
    jq --raw-output .pluggableTransports[] "${PT_CONFIG}" | while read -r line; do
      echo "${line/\$\{pt_path\}/${PT_PATH}}" >> "$TORRC_DEFAULTS"
    done
  done

  # Write Default Bridge Prefs
  echo "# Tor Launcher preferences (default bridges):" >> "$GENERATEDPREFSPATH"
  RECOMMMENDED_DEFAULT=$(jq -r .recommendedDefault "${PT_CONFIG}")
  echo "pref(\"extensions.torlauncher.default_bridge_recommended_type\", \"${RECOMMMENDED_DEFAULT}\");" >> "$GENERATEDPREFSPATH"

  # Writes bridge-line prefs for a given bridge type
  function bridges_conf {
    local bridge_type="$1"
    local i=1
    jq -r ".bridges.\"$bridge_type\" | .[]" "${PT_CONFIG}" | while read -r line; do
      echo "pref(\"extensions.torlauncher.default_bridge.$bridge_type.$i\", \"$line\");" >> "$GENERATEDPREFSPATH"
      i=$((i + 1))
    done
  }

  # Iterate over our bridge types and write default bridgelines for each
  for bridge_type in $(jq -r ".bridges | keys[]" "${PT_CONFIG}"); do
    bridges_conf $bridge_type
  done
[% END -%]

[% IF c("var/linux") && c("var/tor-browser") %]
  chmod 700 ${TB_STAGE_DIR}/Browser/[% c('var/ProjectName') %]/Data/Browser
  chmod 700 ${TB_STAGE_DIR}/Browser/TorBrowser/Data/Tor
[% END %]

# With multi-lingual builds, we use "ALL" in the package name as the locale for
# update purposes. But we do not include "ALL" in the name of the directory that
# is inside the package (in other words, users will not see tor-browser_ALL
# after they install Tor Browser).
PKG_LOCALE="ALL"
PKG_DIR='[% c("var/project-name") %]'

for tbdir in "${TBDIRS[@]}"
do
  tbdir="$tbdir[% IF c('var/macos') %]/Contents/Resources[% END %]/browser/"
  pushd "$tbdir"
  unzip omni.ja defaults/preferences/[% c("var/prefs_file") %] || [ $? -lt 3 ]
  # Append our built extension-overrides.js to the preferences file
  cat "$GENERATEDPREFSPATH" >> defaults/preferences/[% c("var/prefs_file") %]
  cp defaults/preferences/[% c("var/prefs_file") %] $rootdir
  [% c("touch") %] defaults/preferences/[% c("var/prefs_file") %]
  zip -Xm omni.ja defaults/preferences/[% c("var/prefs_file") %]
  rm -rf defaults
  [% IF c("var/tor-browser") %]
    # create tbb_version.json file for tor-browser#25020
    echo '{"version":"[% c("var/torbrowser_version") %]","architecture":"[% c("var/mar_osname") %]","channel":"[% c("var/channel") %]","locale":"en-US"}' > ../tbb_version.json
  [% END -%]
  popd
done

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

  mv $rootdir/windows-installer $distdir/windows-installer
  cat > $distdir/windows-installer/browser-portable.nsi << 'BROWSER_NSI'
[% INCLUDE 'windows-installer.nsi' %]
BROWSER_NSI
  [% IF c('var/mullvad-browser') -%]
    cat > $distdir/windows-installer/browser-system.nsi << 'BROWSER_NSI'
[% INCLUDE 'windows-installer.nsi' system_install_mode = 1 %]
BROWSER_NSI
  [% END -%]
  mv ${TB_STAGE_DIR} $distdir/windows-installer/"[% c('var/Project_Name') %]"
  mv $distdir/windows-installer ${TB_STAGE_DIR}
[% END %]

[% IF c("var/macos_universal") -%]
  # unify.py requires lipo, so we need to add cctools in the PATH
  tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/macosx-toolchain') %]
  export PATH="/var/tmp/dist/macosx-toolchain/cctools/bin:$PATH"
  firefox_src=/var/tmp/dist/firefox-src
  mkdir -p $firefox_src
  tar -C $firefox_src -xf $rootdir/[% c('input_files_by_name/src-firefox') %]
  firefox_src=$(echo $firefox_src/firefox-*)
  # Temporarily move noscript outside of $TBDIR to avoid error when running unify.py:
  #   File "/var/tmp/dist/firefox-src/firefox-69721baf14f0/python/mozbuild/mozpack/mozjar.py", line 452, in _getreader
  #     raise JarReaderError(
  # mozpack.mozjar.JarReaderError: Central directory and file header mismatch. Corrupted archive?
  #
  # See https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/issues/40439#note_2838724
  mkdir $rootdir/extensions
  mv "$TBDIR/$EXTSPATH/"* $rootdir/extensions
  MOZ_AUTOMATION=1 $firefox_src/mach python3 $firefox_src/toolkit/mozapps/installer/unify.py "$TBDIR" "$TBDIR_AARCH64"
  mkdir -p "$TBDIR/$EXTSPATH"
  mv $rootdir/extensions/* "$TBDIR/$EXTSPATH/"
  rm -Rf "$TBDIR_AARCH64"
[% END -%]

[% IF c("var/windows") %]
  TBDIR="$distdir/$PKG_DIR/[% c("var/Project_Name") %]/Browser"
[% ELSIF c("var/macos") %]
  TBDIR="$distdir/$PKG_DIR/[% c("var/Project_Name") %].app"
[% ELSE %]
  TBDIR="$distdir/$PKG_DIR/Browser"
[% END %]

cat > "$scripts_dir/create-$PKG_DIR" << SCRIPT_EOF
#!/bin/bash
set -e
cp -a ${TB_STAGE_DIR} $distdir/$PKG_DIR

[% IF c("var/updater_enabled") -%]
  pushd "$TBDIR[% IF c("var/macos") %]/Contents/Resources/[% END %]"
  rm -f precomplete
  python3 $MARTOOLS/createprecomplete.py
  popd
[% END -%]
cd $distdir

[% IF c("var/build_mar") && c("var/updater_enabled") -%]
  # Create full MAR file and compressed package.
  [% SET mar_file = c("var/project-name") _ '-' _ c("var/mar_osname") _ '-' _ c("var/torbrowser_version") _ '_${PKG_LOCALE}.mar' %]
  MAR=$MARTOOLS/mar \
  MOZ_PRODUCT_VERSION=[% c("var/torbrowser_version") %] \
  MAR_CHANNEL_ID=[% c("var/mar_channel_id") %] \
  $MARTOOLS/make_full_update.sh -q $OUTDIR/[% mar_file %] "$TBDIR"
[% END -%]

[% IF c("var/linux") %]
  [% IF c("var/tor-browser") %]
    # We need the old fontconfig files only when updating from old installations
    # that include it, but do not add it to new packages!
    # Remove once we do a watershed release.
    rm -rf "$TBDIR/TorBrowser/Data/fontconfig"
  [% END -%]
  [% c('tar', {
        tar_src => [ '$PKG_DIR' ],
        tar_args => '-cJf $OUTDIR/' _ c("var/project-name") _ '-' _ c("var/osname") _ '-' _ c("var/torbrowser_version") _ '.tar.xz',
    }) %]
[% ELSIF c("var/macos") %]
  [% c('var/ddmg', {
        dmg_src => '"$PKG_DIR"',
        dmg_out => '$OUTDIR/' _ c('var/project-name') _ '-' _ c("var/mar_osname") _ '-' _ c("var/torbrowser_version") _ '.dmg',
    }) %]
[% ELSIF c("var/windows") %]
  find "$PKG_DIR" -exec [% c("touch") %] {} \;
  pushd "$PKG_DIR"
  makensis browser-portable.nsi
  # Working around NSIS braindamage
  python3 $rootdir/pe_checksum_fix.py browser-install.exe
  mv browser-install.exe $OUTDIR/[% c("var/project-name") %]-[% c("var/osname") %]-portable-[% c("var/torbrowser_version") %].exe
  [% IF c('var/mullvad-browser') -%]
    makensis browser-system.nsi
    python3 $rootdir/pe_checksum_fix.py browser-install.exe
    mv browser-install.exe $OUTDIR/[% c("var/project-name") %]-[% c("var/osname") %]-install-[% c("var/torbrowser_version") %].exe
  [% END -%]
  popd
[% END %]
rm -rf $distdir/${PKG_DIR}
SCRIPT_EOF

[% IF c("var/updater_enabled") -%]
  cp $rootdir/[% c('input_files_by_name/firefox') %]/mar-tools-*.zip "$OUTDIR"/
[% END -%]
[% IF c("var/linux-x86_64") -%]
  # TODO: See if we can make symbols also for Linux i686, see tor-browser#42146.
  cp $rootdir/[% c('input_files_by_name/firefox') %]/browser-debug-symbols.tar.xz "$OUTDIR/[% c('var/project-name') %]-debug-symbols-[% c('var/mar_osname') %]-[% c('var/torbrowser_version') %].tar.xz"
  [% IF !c("var/asan") -%]
    cp $rootdir/[% c('input_files_by_name/firefox') %]/geckodriver.tar.xz "$OUTDIR/geckodriver-[% c('var/mar_osname') %]-[% c('var/torbrowser_version') %].tar.xz"
  [% END -%]
[% ELSIF c("var/windows") -%]
  cp $rootdir/[% c('input_files_by_name/firefox') %]/browser-debug-symbols.zip "$OUTDIR/[% c('var/project-name') %]-debug-symbols-[% c('var/mar_osname') %]-[% c('var/torbrowser_version') %].zip"
[% END -%]
[%IF c("var/tor-browser") -%]
  tor_expert_bundle_src="[% c("input_files_by_name/tor-expert-bundle") %]"
  # strip off trailing "$buildid.tar.gz"
  tor_expert_bundle_dest=${tor_expert_bundle_src:0:-14}.tar.gz
  cp $rootdir/[% c("input_files_by_name/tor-expert-bundle") %] "$OUTDIR"/$tor_expert_bundle_dest
  [% IF c("var/macos_universal") %]
    tor_expert_bundle_src="[% c('input_files_by_name/tor-expert-bundle-aarch64') %]"
    # strip off trailing "$buildid.tar.gz"
    tor_expert_bundle_dest=${tor_expert_bundle_src:0:-14}.tar.gz
    cp $rootdir/[% c('input_files_by_name/tor-expert-bundle-aarch64') %] "$OUTDIR"/$tor_expert_bundle_dest
  [% END -%]
[% END -%]
[% IF c("var/build_infos_json") -%]
  cp $rootdir/[% c('input_files_by_name/firefox') %]/build-infos.json "$OUTDIR"/build-infos-[% c("var/mar_osname") %].json
[% END -%]

chmod 775 $rootdir/run_scripts "$scripts_dir"/*
$rootdir/run_scripts [% c("num_procs") %] "$scripts_dir"
