# Maintainer (arch:firefox): Jan Alexander Steffens (heftig) <heftig@archlinux.org>
# Contributor: Ionut Biru <ibiru@archlinux.org>
# Contributor: Jakub Schmidtke <sjakub@gmail.com>
# Contributor: Henry Jensen <hjensen@connochaetos.org>
# Maintainer (archarm:firefox): Kevin Mihelich <kevin@archlinuxarm.org>
# Maintainer (arch32:firefox): Andreas Baumann <mail@andreasbaumann.cc>
# Contributor: Erich Eckner <git@eckner.net>
# Contributor: Andreas Grapentin <andreas@grapentin.org>
# Contributor: Luke Shumaker <lukeshu@parabola.nu>
# Contributor: André Silva <emulatorman@hyperbola.info>
# Contributor: Márcio Silva <coadde@hyperbola.info>
# Contributor: fauno <fauno@kiwwwi.com.ar>
# Contributor: vando <facundo@esdebian.org>
# Contributor: Figue <ffigue at gmail>
# Contributor: evr <evanroman at gmail>
# Contributor: Muhammad 'MJ' Jassim <UnbreakableMJ@gmail.com>
# Contributor: vando <facundo@esdebian.org>
# Contributor: taro-k <taro-k@movasense_com>
# Contributor: Michał Masłowski <mtjm@mtjm.eu>
# Contributor: Luke R. <g4jc@openmailbox.org>
# Contributor: Isaac David <isacdaavid@isacdaavid.info>
# Contributor: bill-auger <bill-auger@programmer.net>
# Contributor: grizzlyuser <grizzlyuser@protonmail.com>


# parabola changes and rationale:
# libre:
#  - Modify the add-ons GUI to search the Gnuzilla Mozzarella website
#    instead of the Mozilla add-ons website, which hosts non-free addons
#  - Disable EME, which is implemented via the non-free libWideVine CDM
#  - Disable Normandy that let Mozilla push messages with recommendations
#    of nonfree software
#  - Make Remote Settings work completely offline using local data
#  - Use system python libs. The arch package uses 'pip' to download
#    dependencies from the internet at build-time, despite that those needed
#    dependencies are already packaged in the arch repos. So strictly-speaking,
#    the package is not built from source, as some sources will be missing
#    from the published source package, and will not be required as makedepends.
#
# technical:
#  - build 32-bit arches with GCC instead of clang
#  - disable rust-SIMD, LTO, PGO, and skip profiling build for armv7h and i686
#  - allow skipping profiling build for x86_64 (_SKIP_PGO).
#    this is to avoid OOM problems, and occasional deadlocks in some versions,
#    which expect active netwokring or internet access at build time.
#  - prefer as many system libs as possible, over their vendored couterparts
#  - Rebrand to Iceweasel, per the mozilla trademark policy, due to the FSDG changes
#  - set user profile directory to ~/.mozilla/iceweasel
#
# privacy:
#  - Remove Google API keys and usage
#  - Disable Mozilla telemetry and crash reporting
#    (good manners because of all of the other patching we're doing)
#  - do not compile/upload remote debug symbols


# NOTE: This PKGBUILD is kept in-sync, as closely as possible,
#       with arch{,arm,32} (firefox), and parabola {iceweasel,icecat},
#       for the sake of documentation and cleaner diffs.
#       That also helps to identify which changes were made by Parabola vs upstream.
#       Therefore, this PKGBUILD may declare blacklisted dependencies, non-free sources,
#       or include code for anti-features; but those will be filtered-out subsequently.
#       Any code which implements an anti-feature should be commented-out;
#       and include an 'anti-feature' comment, for clarity.
#       Any blacklisted dependencies and non-free sources should be filtered,
#       and include a 'non-free' comment, for clarity.
#       Without those over-rides, the resulting program may not be FSDG-fit.
#       Do not circumvent those over-rides, if compiling for the Parabola repos.


pkgname=iceweasel
epoch=1
pkgver=123.0.1
pkgrel=1
pkgrel+=.parabola1
_brandingver=123.0
_brandingrel=1
pkgdesc="Standalone web browser derived from Mozilla Firefox"
url=https://wiki.parabola.nu/Iceweasel
arch=(x86_64)
arch+=(armv7h i686)
license=(
  GPL
  LGPL
  MPL
)
depends=(
  dbus
  ffmpeg
  gtk3
  libpulse
  libxss
  libxt
  mime-types
  nss
  ttf-font
)
makedepends=(
  cbindgen
  clang
  diffutils
  imake
  inetutils
  jack
  lld
  llvm
  mesa
  nasm
  nodejs
  python
  rust
  unzip
  wasi-compiler-rt
  wasi-libc
  wasi-libc++
  wasi-libc++abi
  xorg-server-xvfb
  yasm
  zip
)
makedepends+=(
  git
  imagemagick
  jq
  libxslt
  python-jsonschema
  python-setuptools
  python-typing-extensions
  python-zstandard
  quilt
)
optdepends=(
  'hunspell-en_US: Spell checking, American English'
  'libnotify: Notification integration'
  'networkmanager: Location detection via available WiFi networks'
  'pulseaudio: Audio support'
  'speech-dispatcher: Text-to-Speech'
  'xdg-desktop-portal: Screensharing with Wayland'
)
# install=${pkgname}.install # TODO: redmine #2164
# provides=('firefox')       # TODO: redmine #2164 - currently conflicts with 'your-freedom'
replaces=('firefox')
options=(
  !emptydirs
  !lto
  !makeflags
)
source=(
  https://archive.mozilla.org/pub/firefox/releases/$pkgver/source/firefox-$pkgver.source.tar.xz{,.asc}
  $pkgname.desktop
  identity-icons-brand.svg
)
source=(${source[*]/identity-icons-brand.svg/}) # branding over-ride
source+=(
  https://repo.parabola.nu/other/iceweasel/${pkgname}_${_brandingver}-${_brandingrel}.branding.tar.xz{,.sig}
  9001-FSDG-sync-remote-settings-with-local-dump.patch
  9002-FSDG-preference-defaults.patch
  9003-FSDG-urihandlers.patch
  9004-FSDG-misc.patch
  process-json-files.py
  vendor.js.in
)
source_i686=(
  avoid-libxul-OOM-python-check.patch
  rust-static-disable-network-test-on-static-libraries.patch
  firefox-111.0.1-fdlibm.patch
  fix-i686-build-moz-1792159.patch
  fix-i686-xsimd-incomplete.patch
)
validpgpkeys=(
  # Mozilla Software Releases <release@mozilla.com>
  # https://blog.mozilla.org/security/2023/05/11/updated-gpg-key-for-signing-firefox-releases/
  14F26682D0916CDD81E37B6D61B7B526D98F0353
)
validpgpkeys+=(
  'BFA8008A8265677063B11BF47171986E4B745536' # Andreas Grapentin
  '3954A7AB837D0EA9CFA9798925DB7D9B5A8D4B40' # bill-auger
)

sha256sums=('d5dcb955b65e0f164a90cac0760724486e36e896221b98f244801dfd045d741c'
            'SKIP'
            '9cdc2602661717712092d28bb494e5b48e518cb930898aca85eaf21f91f7ef58') # $pkgname.desktop
                                                                                # identity-icons-brand.svg
sha256sums+=('3a365374e3565a8963b000410cdd863d2fe3b4da9f63aa90d4150d1e1822102b'  # *.branding.tar.xz
             'SKIP'
             'b6b100d7749387362bda9c8c8c19fe742870ec8a7a39172878b8dbfe773efeee' # 9001-FSDG-sync-remote-settings-with-local-dump.patch
             '8f530e41f19675bd74e62f5182f7975a24b690d5d17420fbe8a5365d55b71910' # 9002-FSDG-preference-defaults.patch
             '07d6910ddd07f60b803957259e06e3babee6f072f48c6fe31b906a1ea24e3b62' # 9003-FSDG-urihandlers.patch
             '47050470053380f81391eb0631d9977bcc3abaeab632331bdce8576a0ceae1f9' # 9004-FSDG-misc.patch
             'c1d57c2b5b3621b34a4c5e7cc6e83170cfa576965b341c71e750e610440f490c'  # process-json-files.py
             '86bd54db6026ff65bd24ac4f05d0679a645ff447e2f81b0ee44037c0c4285e06') # vendor.js.in
sha256sums_i686=('62fa060e09b95e92fa81f4ac47c06b03d70c2bbc6cda061d85e965a82730e1c0'  # avoid-libxul-OOM-python-check.patch
                 'b25d9fb901afc5447bcd87416741f705eb7188502e10097387d5b0c86417fd01'  # rust-static-disable-network-test-on-static-libraries.patch
                 'ed3bb281697af7c4353a34067ffb4b18a971d40757bef2d6af3c8bf2d28d42d1'  # firefox-111.0.1-fdlibm.patch
                 '2fb39374fd3d80eea9e346032a2a4b2bc2e357dee7380855b24bcf19b1335d06'  # fix-i686-build-moz-1792159.patch
                 'c3ce181fbb0142055aa6dd17f3cda2ba6a1e54d7a689a8c6e9cce76aa40e6544') # fix-i686-xsimd-incomplete.patch
b2sums=('837f2edf2dcf51f19d8cad1f8234723236f318defa1196885b019e46878b377a24a83093ccbf8ef43e7ea94ddd1520f2918bcea520c59379453d40251ff972d6'
        'SKIP'
        'f86353bbba05d8994db34c6abb66094aa61d2c37c8599930dbe9d215413f0f718a1ce55a8f2d07a65074c3947e28fc80d44c925bd9be239a870f82d2a1803635') # $pkgname.desktop
                                                                                                                                            # identity-icons-brand.svg
b2sums+=('96ee9ddf3306db08e9d3e6efdae87900e088aedebadb4b703524f2396ebd26e67120298bb6ec7fee2363e9fe4a83395b1a314ef34732b059870cdf161eaecc8b'  # *.branding.tar.xz
         'SKIP'
         'adb8c96328cbc6f8c7e50207b89c2d4c68733dd1fdcd341ae2ac4a3a1702430c2e5983e4249682153e0e593e0f54ab0258ed01d849589e8dc77c8729beccf3e7' # 9001-FSDG-sync-remote-settings-with-local-dump.patch
         '97bc57322635a7fa5d55b087303ece6f982104db5ef945393e74722acd783262bcc63e5cd3e5748eae9f07a9add59925898b67a2e20fa8420d4c7bfc4cd39867' # 9002-FSDG-preference-defaults.patch
         'dbb0f9639cbe08bf423faf9e2966b5464a26ab5c6314eea18be0e89edd8ac465bfa04a219821852bdd0801dfed9092999bcca1a982a631035bae9a51408d8dde' # 9003-FSDG-urihandlers.patch
         '1d7c896bc1b447e833e3f15410d5db16983d002042de23f3e456a40e8cca23a2c82db6b0f73b5095b51de4f48258039ab37b410653b7c7e8653d2996eaab2019' # 9004-FSDG-misc.patch
         '74e81a58faa219d6a822caae0212896561ecf8d97f736b9b23c6aec2b6e9dbd284702093ee1c75bd99638d8f86c4755542ae4b0dfa0ce8a25064e3430a6f2135'  # process-json-files.py
         'f3f344196d03499f3f0392d5dfc5310e131d8c85772edd340faf1df3f04ebf2931eb1dda1b7fe6870d61d498618f4d8ae9f1dd446acbe83e0ce324e04b38f3f9') # vendor.js.in
b2sums_i686=('684559d207d33e8b83c70d79ddb8b4d7532f2440895668245856553e02b6c786cf0de776981cdcce2438c7add2d692f4afbc85255949558852bdec9800c59882'  # avoid-libxul-OOM-python-check.patch
             '32c60a9259f9ab6b950c0a3af81e4c36c14160860d3b9da70aa3fbc3676e5fd2b2705b02d7e6b6ac49f9510577de89ab2334abe3b0a126e3d70e65ac42ba62c9'  # rust-static-disable-network-test-on-static-libraries.patch
             '05c7c9727201971650df4ca2e00539767fc9e159539835c641fccab5ec9577a7294e8f62f5d0670158316e5467ea121c03a36fd4ba153e1d60f3402f0430548d'  # firefox-111.0.1-fdlibm.patch
             'd20ce3eff595f85df86eaa0dfb665fc356f8987117a771f76adc4ac12046a7e82b0af182fa99f87ea1362a5026c9d0216c7b714649fef0c7294c61c8e8f4d790'  # fix-i686-build-moz-1792159.patch
             '3e6fd4cebe0fd4c250ccf5b04e12b93e5f4cc2d139301316c987cc07a57b4b6b49b830d745520a82f5ac59da8d17f728a3ecce4dccf21804a2d6a256a6f76472') # fix-i686-xsimd-incomplete.patch

# Google API keys (see http://www.chromium.org/developers/how-tos/api-keys)  # anti-feature
# Note: These are for Arch Linux use ONLY. For your own distribution, please # anti-feature
# get your own set of keys. Feel free to contact foutrelis@archlinux.org for # anti-feature
# more information.                                                          # anti-feature
_google_api_key=                                                             # anti-feature

# Mozilla API keys (see https://location.services.mozilla.com/api)           # anti-feature
# Note: These are for Arch Linux use ONLY. For your own distribution, please # anti-feature
# get your own set of keys. Feel free to contact heftig@archlinux.org for    # anti-feature
# more information.                                                          # anti-feature
_mozilla_api_key=                                                            # anti-feature


## compiler and optimization tweaks ##

# disable PGO
# try this if the build hangs indefinitely - known past causes:
#   * resource exhaustion
#   * a test which misbehaves in environments without networking
readonly _SKIP_PGO=$(case "${CARCH}" in armv7h|i686) echo 1 ;; *) echo 0 ;; esac)

# use GCC vs LLVM
# trying one or the other, may resolve sporadic compiler/linker discrepancies
readonly _USE_ALT_COMPILER=$(case "${CARCH}" in armv7h) echo 0 ;; *) echo 0 ;; esac)

# use 'bfd' linker vs 'lld'
# most significantly, this also disables LTO and debugging
# try this if the build freezes or crashes due to resource exhaustion
# FIXME: x86_64 FTBS with LTO due to resource exhaustion
#        luke added a swapfile to beefcake, because this build crashed the server
#        apparently, a measly 32GB RAM is no longer sufficient to contain this beast
#        the system no longer crashes now; but the build process gets killed instead
#        > clang-15: error: unable to execute command: Killed
readonly _USE_ALT_LINKER=$(case "${CARCH}" in i686|x86_64) echo 1 ;; *) echo 0 ;; esac)


## dependency tweaks ##

case "${CARCH}" in
armv7h)
  makedepends=( ${makedepends[*]/wasi-*/} ) # armv7h has no wasi compiler

  depends+=( libicudata.so libicui18n.so libicuuc.so ) # --with-system-icu
  ;;
i686)
  # NOTE: due to python incompatabilities in arch32,
  #       we are building for i686 against the repos from 2023-06-01 - but ...
  #       the latest 'cbindgen' is required
  makedepends=( ${makedepends[*]/cbindgen/cbindgen=0.26.0} )
  #       and ... nss>=3.94 is required; but it FTBS
  # still FTBS
  ;;
esac


## helpers ##

_check_build_config() {
  pushd "${srcdir}"/firefox-${pkgver} > /dev/null

  echo "Checking build configuration..."

  # Each of the [ARCH-SPECIFIC CONFIG] branches in prepare(), should have prepared a
  # $srcdir/mozconfig file with any arch-specific changes to the Arch x86_64 PKGBUILD.
  # Finally, that file should have been copied to $srcdir/firefox-$pkgver/.mozconfig
  grep '^ac_add_options --with-distribution-id=nu.parabola' .mozconfig &> /dev/null || \
  ! echo "cannot continue without a .mozconfig file"                                || return 1

  if ! [[ "${CARCH}" =~ ^(aarch64|armv7h)$ ]] # ARM has no --disable-eme option
  then grep '^ac_add_options --disable-eme' .mozconfig &> /dev/null   || \
       ! echo ".mozconfig file was not properly treated per the FSDG" || return 1
  fi

  # Configure produces mozinfo.json that reflects current configuration.
  # See build/docs/mozinfo.rst
  ./mach configure

  # In this test, jq collects values of the following keys of mozinfo.json into array,
  # and checks if any of them are not equal to false, in which case it returns "true".
  # E.g. if the value of any key is true or null (in case the key is missing from mozinfo.json),
  # that means the build configuration has to be reworked.
  local obj_directory=$(./mach environment | sed -En '/object directory:/{n;s/^\s+//;p;}')
  local antifeature_keys=(.crashreporter .datareporting .healthreport .normandy .telemetry .updater)
  local antifeatures=()
  echo "obj_directory is: ${obj_directory}"
  for key in ${antifeature_keys[@]}
  do  if   jq -e "${key} != false" "${obj_directory}"/mozinfo.json &> /dev/null
      then antifeatures+=(${key})
      fi
  done
  if   (( ${#antifeatures[@]} ))
  then echo "Some anti-features are not disabled in build configuration files - aborting:"
       printf "  - %s is enabled\n" ${antifeatures[*]}
       return 1
  fi

  popd > /dev/null
}

_check_patching() {
  pushd "${srcdir}"/firefox-${pkgver} > /dev/null

  echo "verifying libre patching"

  # URI protocol handlers
  local uri_handlers=uriloader/exthandler/HandlerList.sys.mjs
  local webmails='google|yahoo'
  local misc_err_msg="9003-FSDG-misc.patch needs reworking"
  grep   'name:'          $uri_handlers | grep    '"KiwiIRC",' &> /dev/null && \
  ! grep 'name:'          $uri_handlers | grep -v '"KiwiIRC",' &> /dev/null && \
  ! grep -E "($webmails)" $uri_handlers                        &> /dev/null || \
  ! echo "${misc_err_msg}"                                                  || \
  return 1

  # services.addons.mozilla.org API endpoint
  local amo_api_endpoint='services.addons.mozilla.org'
  local amo_err_msg="9002-FSDG-preference-defaults.patch needs reworking: AMO API endpoint hostname found in source tree"
  ! grep -qr $amo_api_endpoint &> /dev/null || ! echo "${amo_err_msg}" || return 1

  # Remote Settings
  local settings_server='firefox.settings.services.mozilla.com'
  local settings_err_msg="9001-FSDG-sync-remote-settings-with-local-dump.patch needs reworking"
  ! grep -qr $settings_server &> /dev/null || ! echo "${settings_err_msg}" || return 1

  popd > /dev/null
}


## business ##

prepare() {
  mkdir mozbuild
  cd firefox-$pkgver

  ## technical patching ##

  # Use system python-typing-extensions instead of the old vendored one to avoid
  # unresolvable dependency versions. They are probably downloaded when network
  # connectivity is enabled at built time, but that is not the case for Parabola.
  echo "deleting vendored 'python-typing-extensions'"
  rm -rfv third_party/python/typing_extensions | grep -Fq ''


  ## [ARCH-SPECIFIC PATCHING] ##

  case ${CARCH} in
  aarch64|armv7h)
    # FTBS with LLVM:
    # intl/lwbrk/LineBreaker.cpp:453:3: error: static assertion failed due to requirement 'U_LB_COUNT == mozilla::ArrayLength(sUnicodeLineBreakToClass)': Gecko vs ICU LineBreak class mismatch
    # appears to be: https://bugzilla.mozilla.org/show_bug.cgi?id=1843007#c1
    # but --with-system-icu is still needed
    # crude fix, adapted from linuxfromscratch https://wiki.linuxfromscratch.org/blfs/ticket/18799
    for i in {43..47}; do
      sed '/ZWJ/s/}/,CLASS_CHARACTER&/' -i intl/lwbrk/LineBreaker.cpp
    done
    ;;
  i686)
    # readelf: Error: Unable to seek to 0x801db328 for section headers
    echo "applying avoid-libxul-OOM-python-check.patch"
    patch -p1 -i ../avoid-libxul-OOM-python-check.patch

    # test failure in rust code (complaining about network functions) when PGO is used,
    # see https://bugzilla.mozilla.org/show_bug.cgi?id=1565757
    echo "applying rust-static-disable-network-test-on-static-libraries.patch"
    patch -p1 -i ../rust-static-disable-network-test-on-static-libraries.patch

    # FIXME: this patch is probably temporary - it comes from mozilla
    #          https://bugzilla.mozilla.org/show_bug.cgi?id=1729459
    #        /build/iceweasel/src/firefox-96.0.1/modules/fdlibm/src/math_private.h:34:21:
    #          error: conflicting declaration ‘typedef __double_t double_t’
    #        /usr/include/math.h:156:21: note: previous declaration as ‘typedef long double double_t’
    echo "applying firefox-111.0.1-fdlibm.patch"
    patch -p1 -i "$srcdir/firefox-111.0.1-fdlibm.patch"

    # js/src/jit/shared/AtomicOperations-shared-jit.cpp:88:9: error: ‘AtomicCopyByteUnsynchronized’ was not declared in this scope; did you mean ‘AtomicMemcpyUpUnsynchronized’?
    echo "applying fix-i686-build-moz-1792159.patch"
    patch -p1 -i "$srcdir/fix-i686-build-moz-1792159.patch"

    # https://bugs.archlinux32.org/index.php?do=details&task_id=332
    # dom/base/nsTextFragmentGeneric.h:38:16: error: ‘any’ is not a member of ‘xsimd’
    # dom/base/nsTextFragmentGeneric.h:16:70: error: incomplete type ‘xsimd::batch<short int, xsimd::sse2>’ used in nested name specifier
    # dom/base/nsTextFragmentGeneric.h:35:31: error: ‘xsimd::batch<short int, xsimd::sse2> vectmask’ has incomplete type
    # dom/base/nsTextFragmentGeneric.h:37:64: error: incomplete type ‘xsimd::batch<short int, xsimd::sse2>’ used in nested name specifier
    echo "applying fix-i686-xsimd-incomplete.patch"
    patch -p1 -i "$srcdir/fix-i686-xsimd-incomplete.patch"
    ;;
  x86_64)
    ;;
  esac


  ## general configuration ##

  echo -n "$_google_api_key" >google-api-key
  echo -n "$_mozilla_api_key" >mozilla-api-key

  cat >../mozconfig <<END
ac_add_options --enable-application=browser
mk_add_options MOZ_OBJDIR=${PWD@Q}/obj

ac_add_options --prefix=/usr
ac_add_options --enable-release
ac_add_options --enable-hardening
ac_add_options --enable-optimize
ac_add_options --enable-rust-simd
ac_add_options --enable-linker=lld
ac_add_options --disable-install-strip
ac_add_options --disable-elf-hack
ac_add_options --disable-bootstrap
ac_add_options --with-wasi-sysroot=/usr/share/wasi-sysroot

# Branding
ac_add_options --disable-official-branding                 # branding over-ride
ac_add_options --enable-update-channel=release
ac_add_options --with-distribution-id=nu.parabola          # branding over-ride
ac_add_options --with-branding=browser/branding/${pkgname} # branding over-ride
ac_add_options --with-app-name=${pkgname}                  # branding over-ride
ac_add_options --with-app-basename=${pkgname}              # branding over-ride
ac_add_options --with-unsigned-addon-scopes=app,system
ac_add_options --allow-addon-sideload
# export MOZILLA_OFFICIAL=1                                # branding over-ride
export MOZ_APP_REMOTINGNAME=${pkgname//-/}
export MOZ_TELEMETRY_REPORTING=
export MOZ_REQUIRE_SIGNING=

# Keys
# ac_add_options --with-google-location-service-api-keyfile=${PWD@Q}/google-api-key # anti-feature
# ac_add_options --with-google-safebrowsing-api-keyfile=${PWD@Q}/google-api-key     # anti-feature
# ac_add_options --with-mozilla-api-keyfile=${PWD@Q}/mozilla-api-key                # anti-feature

# System libraries
ac_add_options --with-system-nspr
ac_add_options --with-system-nss

# Features
ac_add_options --enable-alsa
ac_add_options --enable-jack
ac_add_options --disable-crashreporter # anti-feature
ac_add_options --disable-updater
ac_add_options --disable-tests
ac_add_options --disable-eme           # anti-feature
END


  ## [ARCH-SPECIFIC CONFIG] ##

  if   (( _USE_ALT_COMPILER ))
  then cat >> ../mozconfig <<END
export CC=gcc
export CXX=g++
export AR=gcc-ar
export NM=gcc-nm
export RANLIB=gcc-ranlib
END
  fi

  if   (( _USE_ALT_LINKER ))
  then sed -i '/cargo_rustc_flags += -Clto/d' config/makefiles/rust.mk
       cat >> ../mozconfig <<END
ac_add_options --disable-linker=lld
ac_add_options --enable-linker=bfd
ac_add_options --disable-lto
ac_add_options --disable-rust-simd
ac_add_options --disable-debug
ac_add_options --disable-debug-symbols
END
  fi

  case ${CARCH} in
  aarch64|armv7h)
    # experimental/version-specific hacks #

    # ld.lld: error: undefined hidden symbol: std::type_info::operator==(std::type_info const&) const
    echo 'ac_add_options --with-system-icu' >> ../mozconfig


    # archarm configuration #

    # archarm recipe has mozconfig over-rides under the 'general configuration' section
    # NOTE: '--disable-eme' is currently an invalid option for armv7h.
    #       It must be deleted in order to compile.
    #       If ever it becomes valid, it should not be deleted below.
    sed -i '
      /--enable-hardening/d
      /--enable-optimize/d
      /--enable-rust-simd/d
      s| --with-wasi-sysroot=.*| --without-wasm-sandboxed-libraries|
      /--disable-eme/d
    ' ../mozconfig

    if [[ $CARCH == "armv7h" ]]; then
      echo "ac_add_options --disable-elf-hack" >> .mozconfig
      # https://bugzilla.redhat.com/show_bug.cgi?id=1641623
      echo "ac_add_options --disable-av1" >> .mozconfig
      # reduce jobs due to RAM constraints
      MAKEFLAGS="-j4"
      # disable hard-coded LTO
      sed -i '/cargo_rustc_flags += -Clto/d' config/makefiles/rust.mk
      sed -i '/RUSTFLAGS += -Cembed-bitcode=yes/d' config/makefiles/rust.mk
      # increase codegen-units due to RAM constraints
      sed -i 's/codegen-units=1/codegen-units=16/' config/makefiles/rust.mk
      # webrtc on ARMv7 implies android, so disable it
      echo "ac_add_options --disable-webrtc" >> .mozconfig
    elif [[ $CARCH == "aarch64" ]]; then
      echo 'ac_add_options --enable-rust-simd' >> .mozconfig
    fi

    echo 'ac_add_options --enable-optimize="-g0 -O2"' >> .mozconfig
    echo "mk_add_options MOZ_MAKE_FLAGS=\"${MAKEFLAGS}\"" >> .mozconfig

    # archarm `export` commands are under the '[ARCH-SPECIFIC BUILD ENV]' section

    # archarm patching is under the '[ARCH-SPECIFIC PATCHING]' section

    # At this point in the recipe, the arch, arch32, and parabola PKGBUILDs
    # have prepared a temporary ${srcdir}/mozconfig; but the archarm PKGBUILD
    # writes directly to the final firefox-$pkgver/.mozconfig.
    # We allowed .mozconfig to be written above, only to minimize the diff against archarm.
    # For consistency across arches, we append those changes to ${srcdir}/mozconfig now.
    # ${srcdir}/mozconfig will clobber firefox-$pkgver/.mozconfig later, during build().
    cat .mozconfig >> ../mozconfig
    ;;
  i686)
    # experimental/version-specific hacks #


    # arch32 configuration #

    # arch32 `export` commands are under the '[ARCH-SPECIFIC BUILD ENV]' section

    # arch32 recipe has mozconfig over-rides in mozconfig-i686.patch
    # in this recipe, the '_USE_ALT_LINKER' block includes most of them
    cat >>../mozconfig <<END
ac_add_options --disable-webrtc
END

    # arch32 patching is under the '[ARCH-SPECIFIC PATCHING]' section
    ;;
  x86_64)
    ;;
  *) echo "no [ARCH-SPECIFIC CONFIG] for arch: ${CARCH}" ; return 1 ;
    ;;
  esac


  ## branding ##

  local branding_srcdir="${srcdir}"/${pkgname}-${_brandingver}
  local branding_destdir="${srcdir}"/firefox-${pkgver}/browser/branding/${pkgname}
  local tippytopdir="${srcdir}"/firefox-${pkgver}/browser/components/newtab/data/content/tippytop
  local blank_svg='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"></svg>' # TODO: branding package

  # apply branding
  echo "applying parabola branding"
  export QUILT_PATCHES="${branding_srcdir}"/patches
  export QUILT_REFRESH_ARGS='-p ab --no-timestamps --no-index'
  export QUILT_DIFF_ARGS='--no-timestamps'
  export QUILT_PC="${srcdir}"/.pc
  rm -rf -- "${branding_destdir}"
  cp -aT -- "${branding_srcdir}"/branding "${branding_destdir}"
  quilt push -av

  pushd "${branding_destdir}" > /dev/null

  # generate icons, logos, banners
  echo "generating branding images"
  for size in 16 22 24 32 48 64 128 256
  do  rsvg-convert -w ${size} -h ${size}  iceweasel_icon.svg -o default${size}.png
  done
  cp                     iceweasel_logo.svg            content/aboutlogins.svg
  cp                     iceweasel_logo.svg            content/about-logo.svg
#  cp                      iceweasel_logo.svg             content/about-logo.svg # RuntimeError: File "about-logo.svg" not found in browser/branding/iceweasel/content
  rsvg-convert -a -w 192 iceweasel_logo.svg         -o content/about-logo.png
  rsvg-convert -a -w 384 iceweasel_logo.svg         -o content/about-logo@2x.png
  cp                     content/about-logo.png        content/about-logo-private.png
  cp                     content/about-logo@2x.png     content/about-logo-private@2x.png
  echo "${blank_svg}"                                > content/$pkgname-symbolic.svg # TODO: branding package
  cp                     content/$pkgname-symbolic.svg "${srcdir}"/identity-icons-brand.svg # minimize diff (in package())
  cp                     ../unofficial/document.ico    document.ico

  popd > /dev/null

  # custom new tab page
  # FIXME: the newtab page (aka "Start Page") has changed significantly
  #        the new upstream start page ('activity-streams') is an add-on now
  #        it must be forked and customized externally, then copied into the browser tree
  #        see: the branding-dev-build/ dir on the '68.0' branch of the branding git repo
  #        some of the branding components above and commented out below may no longer be used
  #        the following section aims to restore something similar
  #          to the previous parabola-branded "start page"
  #        once it is working well, all of these comments should be removed
  #          and any unused branding components may be deleted from the branding package
  # Put "Start Page" branding images in the source code
  # install -m644 -t browser/base/content/abouthome -- \
  #   "${branding_srcdir}"/branding/{drm-free,gnu_headshadow,parabola-banner}.png
  # install -m644 -t browser/extensions/onboarding/content/img -- \
  #   "${branding_srcdir}"/branding/watermark.svg

  # process default Top Sites and their icons
  echo "deleting unused \"Top Sites\""
  find "${tippytopdir}" -type f    \
       -not -name 'wikipedia-org*' \
       -not -name 'top_sites.json' \
       -exec rm {} \;
  [[ "${CARCH}" != armv7h ]] || export MAGICK_TIME_LIMIT=300 # magick: time limit exceeded
  for image in "${branding_srcdir}"/tippytop/*.svg; do
    local outname=$(basename -s .svg "${image}")
    local size=$(identify -format '%wx%h' "${tippytopdir}"/images/wikipedia-org@2x.png)
    local background=$( [[ "${outname}" == 'gnu' ]] && echo 'white' || echo 'none' )
    magick -density 300 ${image}                           \
           -gravity center -resize ${size} -extent ${size} \
           "${tippytopdir}"/images/${outname}@2x.png

    size=256x256
    magick -density 300 -background ${background} ${image} \
           -gravity center -resize ${size} -extent ${size} \
           -define icon:auto-resize=64,48,32,16            \
           "${tippytopdir}"/favicons/${outname}.ico
  done

  # misc branding
  sed -i "s|({ \$bits }-bit)|($CARCH)|" browser/locales/en-US/browser/aboutDialog.ftl


  ## search-engines ##

  pushd browser/components/search/extensions > /dev/null

  # Delete unused search engine configs
  echo "deleting unused search engine configs"
  find -mindepth 1 -maxdepth 1 \
       -not -name ddg          \
       -not -name wikipedia    \
       -exec rm -fr {} \;

  popd > /dev/null


  ## libre patching ##

  # Upstream tarball can contain some ignored cruft,
  # including binaries (for example, python3).
  echo 'Removing files specified in .gitignore...'
  git init -b master && git clean -dfX                                      \
    --exclude='!ipc/chromium/src/third_party/libevent/evconfig-private.h'   \
    --exclude='!toolkit/crashreporter/google-breakpad/src/third_party/lss/' \
    --exclude='!third_party/python/**/*.egg-info/'
  rm -rf .git

  # Remove test-related networking dumps, because they contain code from
  # some Amazon webpage with no clear licensing, thus nonfree.
  # Also they interfere with checking of Remote Settings patching done later,
  # because communication with RS server has been captured in them too.
  rm python/mozperftest/mozperftest/system/example.zip
  rm testing/mozbase/mozproxy/tests/files/mitm5-linux-firefox-amazon.zip

  # Disable/neutralize Remote Settings (as best we can)
  echo "applying 9001-FSDG-sync-remote-settings-with-local-dump.patch"
  git apply ../9001-FSDG-sync-remote-settings-with-local-dump.patch

  # Disable various components at the source level
  sed -i 's/;1/;0/' toolkit/components/telemetry/components.conf
  sed -Ei 's/((MOZ_SERVICES_HEALTHREPORT|MOZ_NORMANDY).+)True/\1False/' browser/moz.configure
  #sed -i 's/;1/;0/' browser/experiments/Experiments.manifest
  #sed -i '/pocket/d'          browser/extensions/moz.build
  #sed -i '/activity-stream/d' browser/extensions/moz.build

  python ../process-json-files.py "${srcdir}"/firefox-${pkgver} "${branding_srcdir}"

  # disable various phone-home/goelocation anti-featires
  echo "applying 9002-FSDG-preference-defaults.patch"
  patch -Np1 --no-backup-if-mismatch -i "${srcdir}"/9002-FSDG-preference-defaults.patch

  # over-ride/install default URI protocol handlers
  echo "applying 9003-FSDG-urihandlers.patch"
  patch -Np1 --no-backup-if-mismatch -i "${srcdir}"/9003-FSDG-urihandlers.patch

  # Remove remaining non-free bits
  echo "applying 9004-FSDG-misc.patch"
  patch -Np1 --no-backup-if-mismatch -i "${srcdir}"/9004-FSDG-misc.patch

  echo "removing remaining non-free bits"
  rm -v toolkit/crashreporter/tools/upload_symbols.py
  rm -frv third_party/rust/winapi-{i686,x86_64}-pc-windows-gnu/**/*.a | \
  sed 's|/[^/]*\.a$|/*.a|' | sort -u

  ## patching sanity checks ##
  _check_patching
}

build() {
  cd firefox-$pkgver

  ## build env ##

  export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system # parabola policy
  export MOZBUILD_STATE_PATH="$srcdir/mozbuild"
  export MOZ_BUILD_DATE="$(date -u${SOURCE_DATE_EPOCH:+d @$SOURCE_DATE_EPOCH} +%Y%m%d%H%M%S)"
  export MOZ_NOSPAM=1

  # malloc_usable_size is used in various parts of the codebase
  CFLAGS="${CFLAGS/_FORTIFY_SOURCE=3/_FORTIFY_SOURCE=2}"
  CXXFLAGS="${CXXFLAGS/_FORTIFY_SOURCE=3/_FORTIFY_SOURCE=2}"

  # LTO needs more open files
  ulimit -n 4096


  ## [ARCH-SPECIFIC BUILD ENV] ##

  case ${CARCH} in
  aarch64|armv7h)
    export MOZ_DEBUG_FLAGS=" "
    export CFLAGS+=" -g0"
    export CXXFLAGS+=" -g0"
    export LDFLAGS+=" -Wl,--no-keep-memory"
    export RUSTFLAGS+=" -Cdebuginfo=0 -Clto=off"

    # clang-16: warning: argument unused during compilation: '-fstack-clash-protection' [-Wunused-command-line-argument]
    export CFLAGS+=' -Wno-unused-command-line-argument'
    export CXXFLAGS+=' -Wno-unused-command-line-argument'

    if ! (( _USE_ALT_COMPILER ))
    then # warning: obj/dist/system_wrappers/cmath:3:15: fatal error: 'cmath' file not found
         export CFLAGS+="   -I/usr/include/c++/12.1.0 -I/usr/include/c++/12.1.0/armv7l-unknown-linux-gnueabihf"
         export CXXFLAGS+=" -I/usr/include/c++/12.1.0 -I/usr/include/c++/12.1.0/armv7l-unknown-linux-gnueabihf"

         # clang-16: error: unknown argument: '-fvar-tracking-assignments'
         export CFLAGS="${CFLAGS/-fvar-tracking-assignments/}"
         export CXXFLAGS="${CXXFLAGS/-fvar-tracking-assignments/}"
    fi
    ;;
  i686)
    # -fno-plt with cross-LTO -> LLVM ERROR: Function Import: link error
    CFLAGS="${CFLAGS/-fno-plt/}"
    CXXFLAGS="${CXXFLAGS/-fno-plt/}"

    # try hard to tell ld and rust not to use too much memory (no lto, no debug info, etc.)
    export RUSTFLAGS+=" -Cdebuginfo=0 -Clto=off"
    export LDFLAGS+=" -Wl,--no-keep-memory " # -Wl,--reduce-memory-overheads -Wl,--max-cache-size=16384000 "
    export MOZ_SOURCE_CHANGESET="DEVEDITION_${pkgver//./_}_RELEASE"

#     export MOZ_MAKE_FLAGS=-j2

    # libvpx has some hard-coded compiler flags for MMX, SSE, SSE2, use the correct one
    # per CARCH (75.0 uses an intrisic _mm_empty now, which required the corresponding
    # architecture flag to be preset - before it was merely embedding some assembly
    # code with EMMS
    export CFLAGS+=" -mmmx"
    export CXXFLAGS+=" -mmmx"
    ;;
  x86_64)
    ;;
  *) echo "no [ARCH-SPECIFIC BUILD ENV] for arch: ${CARCH}" ; return 1 ;
    ;;
  esac
  export CFLAGS
  export CXXFLAGS


  ## [ARCH-SPECIFIC BUILD CONFIG] ##

  case ${CARCH} in
  aarch64|armv7h)
    ;;
  i686)
    # avoid excessive debug symbols in rust leading to out-of-memory situations
    sed -i "s/debug_info = '\''2'\''/debug_info = '\''0'\''/" build/moz.configure/toolchain.configure
    ;;
  x86_64)
    ;;
  *) echo "no [ARCH-SPECIFIC BUILD CONFIG] for arch: ${CARCH}" ; return 1 ;
    ;;
  esac


  ## PGO build ##

  if (( _SKIP_PGO ))
  then
    # skipping "3-tier PGO" "instrumented browser"; so the final .mozconfig is ready now
    cp ../mozconfig .mozconfig
  else
    # Do 3-tier PGO
    echo "Building instrumented browser..."
    cat >.mozconfig ../mozconfig - <<END
ac_add_options --enable-profile-generate=cross
END
    _check_build_config
    ./mach build

    echo "Profiling instrumented browser..."
    ./mach package
    LLVM_PROFDATA=llvm-profdata \
      JARLOG_FILE="$PWD/jarlog" \
      xvfb-run -s "-screen 0 1920x1080x24 -nolisten local" \
      ./mach python build/pgo/profileserver.py

    stat -c "Profile data found (%s bytes)" merged.profdata
    test -s merged.profdata

    stat -c "Jar log found (%s bytes)" jarlog
    test -s jarlog

    echo "Removing instrumented browser..."
    ./mach clobber

    echo "Building optimized browser..."
    cat >.mozconfig ../mozconfig - <<END
ac_add_options --enable-lto=cross,full
ac_add_options --enable-profile-use=cross
ac_add_options --with-pgo-profile-path=${PWD@Q}/merged.profdata
ac_add_options --with-pgo-jarlog=${PWD@Q}/jarlog
END
  fi # _SKIP_PGO


  ## sanity checks ##

  _check_build_config


  ## main build ##

  (( ! _SKIP_PGO )) ||
  echo "Building optimized browser..."
  ./mach build
}

package() {
  export MOZBUILD_STATE_PATH="$srcdir/mozbuild"         # needed for `{libre,}makepkg -R`
  export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system # needed for `{libre,}makepkg -R`

  cd firefox-$pkgver
  DESTDIR="$pkgdir" ./mach install

  local vendorjs="$pkgdir/usr/lib/$pkgname/browser/defaults/preferences/vendor.js"
  install -Dvm644 /dev/stdin "$vendorjs" <<END
// Use LANG environment variable to choose locale
pref("intl.locale.requested", "");

// Use system-provided dictionaries
pref("spellchecker.dictionary_path", "/usr/share/hunspell");

// Disable default browser checking.
pref("browser.shell.checkDefaultBrowser", false);

// Don't disable extensions in the application directory
pref("extensions.autoDisableScopes", 11);

// Enable GNOME Shell search provider
pref("browser.gnome-search-provider.enabled", true);
END

  # Parabola additions to vendor.js
  cat "${srcdir}"/vendor.js.in >> "${vendorjs}"

  local distini="$pkgdir/usr/lib/$pkgname/distribution/distribution.ini"
  install -Dvm644 /dev/stdin "$distini" <<END
[Global]
id=parabola
version=(${_brandingver}-${_brandingrel} branding)
about=${pkgname^} for Parabola GNU/Linux-libre
about.en-US=${pkgname^} for Parabola GNU/Linux-libre
about.eo=${pkgname^} por Parabola GNU/Linux-libre
about.es-ES=${pkgname^} para Parabola GNU/Linux-libre
about.gl=${pkgname^} para Parabola GNU/Linux-libre
about.pt-BR=${pkgname^} para Parabola GNU/Linux-libre

[Preferences]
app.distributor=parabola
app.distributor.channel=$pkgname
app.partner.parabola=parabola
END

  local i theme=official
  theme=$pkgname # NOTE: browser/branding/$theme is $branding_destdir in prepare()
  for i in 16 22 24 32 48 64 128 256; do
    install -Dvm644 browser/branding/$theme/default$i.png \
      "$pkgdir/usr/share/icons/hicolor/${i}x${i}/apps/$pkgname.png"
  done
  install -Dvm644 browser/branding/$theme/content/about-logo.png \
    "$pkgdir/usr/share/icons/hicolor/192x192/apps/$pkgname.png"
  install -Dvm644 browser/branding/$theme/content/about-logo@2x.png \
    "$pkgdir/usr/share/icons/hicolor/384x384/apps/$pkgname.png"
  install -Dvm644 browser/branding/$theme/content/about-logo.svg \
    "$pkgdir/usr/share/icons/hicolor/scalable/apps/$pkgname.svg"
  install -Dvm644 ../identity-icons-brand.svg \
    "$pkgdir/usr/share/icons/hicolor/symbolic/apps/$pkgname-symbolic.svg"

  install -Dvm644 ../$pkgname.desktop \
    "$pkgdir/usr/share/applications/${pkgname//-/}.desktop"

  # Install a wrapper to avoid confusion about binary path
  install -Dvm755 /dev/stdin "$pkgdir/usr/bin/$pkgname" <<END
#!/bin/sh
exec /usr/lib/$pkgname/firefox "\$@"
END
  sed -i "s|/firefox |/${pkgname} |" "$pkgdir/usr/bin/$pkgname" # minimize diff


  ## [ARCH-SPECIFIC INSTALL] ##

  case ${CARCH} in
  aarch64|armv7h)
    ;;
  i686)
    # libxul.so cannot find it's libraries
    install -dm 755 "${pkgdir}/etc/ld.so.conf.d"
    echo "/usr/lib/${pkgname}" > "${pkgdir}"/etc/ld.so.conf.d/${pkgname}.conf
    ;;
  x86_64)
    ;;
  *) echo "no [ARCH-SPECIFIC INSTALL] for arch: ${CARCH}" ; return 1 ;
    ;;
  esac

  # Replace duplicate binary with wrapper
  # https://bugzilla.mozilla.org/show_bug.cgi?id=658850
  ln -srfv "$pkgdir/usr/bin/$pkgname" "$pkgdir/usr/lib/$pkgname/firefox-bin"
  mv "$pkgdir/usr/lib/$pkgname/firefox-bin" "$pkgdir/usr/lib/$pkgname/$pkgname-bin" # minimize diff

  # Use system certificates
  local nssckbi="$pkgdir/usr/lib/$pkgname/libnssckbi.so"
  if [[ -e $nssckbi ]]; then
    ln -srfv "$pkgdir/usr/lib/libnssckbi.so" "$nssckbi"
  fi

  # Configure GNOME Shell search provider
  local sprovider="$pkgdir/usr/share/gnome-shell/search-providers/$pkgname.search-provider.ini"
  install -Dvm644 /dev/stdin "$sprovider" <<END
[Shell Search Provider]
DesktopId=${pkgname//-/}.desktop
BusName=org.mozilla.${pkgname//-/}.SearchProvider
ObjectPath=/org/mozilla/${pkgname//-/}/SearchProvider
Version=2
END
}
