# Maintainer: Felix Yan <felixonmars@archlinux.org>
# Maintainer: Daniel M. Capella <polyzen@archlinux.org>
# Contributor  Bartłomiej Piotrowski <bpiotrowski@archlinux.org>
# Contributor: Thomas Dziedzic < gostrc at gmail >
# Contributor: James Campos <james.r.campos@gmail.com>
# Contributor: BlackEagle < ike DOT devolder AT gmail DOT com >
# Contributor: Dongsheng Cai <dongsheng at moodle dot com>
# Contributor: Masutu Subric <masutu.arch at googlemail dot com>
# Contributor: TIanyi Cui <tianyicui@gmail.com>

pkgname=nodejs
pkgver=26.5.1
pkgrel=2
pkgdesc='Evented I/O for V8 javascript ("Current" release)'
arch=('x86_64')
url='https://nodejs.org/'
license=('MIT')
depends=(
  'ada'
  'brotli'
  'c-ares'
  'icu'
  'libffi'
  'libnghttp2'
  'libnghttp3'
  'libngtcp2'
  'libuv'
#  'llhttp'
  'openssl'
  'simdjson'
#  'simdutf'
#  'v8'
  'zlib'
  'zstd'
)
makedepends=(
  'git'
  'ninja'
  'procps-ng'
  'python'
)
optdepends=('npm: nodejs package manager')
source=("git+https://github.com/nodejs/node.git#tag=v$pkgver?signed")

sha512sums=('6442f5406f15b7d444f1e6868acc4f17cb1b34675f5b0771b3e03429b25ea4731c38c84a85ef368f05e2a4b277e2cfdabe0c80f9323f618236bd59e49aa957a1')
validpgpkeys=(
  '8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600' # Michaël Zasso (Targos) <targos@protonmail.com>
  '890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4' # RafaelGSS <rafael.nunu@hotmail.com>
  'C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C' # Richard Lau <rlau@redhat.com>
  'C0D6248439F1D5604AAFFB4021D900FFDB233756' # Antoine du Hamel <duhamelantoine1995@gmail.com>
  '5BE8A3F6C8A5C01D106C0AD820B1A390B168D356' # Antoine du Hamel <antoine.duhamel@rosa.be>
  '108F52B48DB57BB0CC439B2997B01419BD92F80A' # Ruy Adorno <ruyadorno@hotmail.com>
)

_common_flags=(
  -fno-semantic-interposition
  -Wno-error=coverage-mismatch
)

_configure_args=(
  --ninja
  --enable-lto
  --prefix=/usr
  --with-intl=system-icu
  --without-npm
  --shared-ada
  --shared-brotli
  --shared-cares
  --shared-ffi
  --shared-libuv
  --shared-nghttp2
  --shared-nghttp3
  --shared-ngtcp2
  --shared-openssl
  --shared-simdjson
  --shared-zlib
  --shared-zstd
  # --shared-http-parser
  # --shared-simdutf
  # --shared-v8
)

_set_flags() {
  # /usr/lib/libnode.so uses malloc_usable_size, which is incompatible with fortification level 3
  CFLAGS="${CFLAGS/_FORTIFY_SOURCE=3/_FORTIFY_SOURCE=2}"
  CXXFLAGS="${CXXFLAGS/_FORTIFY_SOURCE=3/_FORTIFY_SOURCE=2}"

  export CFLAGS+=" ${_common_flags[*]}"
  export CXXFLAGS+=" ${_common_flags[*]}"
}

build() {
  _set_flags
  cd node

  # PGO: instrumented build
  ./configure "${_configure_args[@]}" --enable-pgo-generate
  make

  # PGO: generate profile data via test suite (broad coverage)
  make test || true

  # PGO: generate profile data via synthetic workload (deep coverage of hot paths)
  out/Release/node -e "
    const crypto = require('crypto');
    const zlib = require('zlib');
    const { Readable, Writable } = require('stream');
    const { URL } = require('url');

    // Crypto - heavily used in TLS/HTTPS
    for (let i = 0; i < 5000; i++) {
      crypto.createHash('sha256').update('bench').digest('hex');
      crypto.createHash('md5').update('bench').digest('hex');
      crypto.randomBytes(64);
    }

    // JSON parse/stringify - extremely common in APIs
    const obj = {users: Array.from({length: 100}, (_, i) => ({id: i, name: 'user' + i, active: true}))};
    for (let i = 0; i < 5000; i++) {
      JSON.parse(JSON.stringify(obj));
    }

    // Buffer operations
    for (let i = 0; i < 5000; i++) {
      const b = Buffer.alloc(4096);
      b.fill('x');
      b.toString('utf8');
      b.toString('base64');
      Buffer.concat([b, b]);
    }

    // URL parsing
    for (let i = 0; i < 5000; i++) {
      new URL('https://example.com/path/to/resource?key=value&foo=bar#section');
    }

    // Zlib compress/decompress
    const data = Buffer.alloc(16384, 'abcdefgh');
    for (let i = 0; i < 500; i++) {
      const compressed = zlib.deflateSync(data);
      zlib.inflateSync(compressed);
    }

    // Stream pipeline
    for (let i = 0; i < 500; i++) {
      const chunks = [];
      const r = new Readable({read() { this.push(Buffer.alloc(1024, 'a')); this.push(null); }});
      const w = new Writable({write(chunk, enc, cb) { chunks.push(chunk); cb(); }});
      r.pipe(w);
    }
  "

  # PGO: optimized build using collected profile data
  ./configure "${_configure_args[@]}" --enable-pgo-use
  make
}

package() {
  _set_flags
  cd node
  make DESTDIR="$pkgdir" install
  install -Dm644 LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname
}

# vim:set ts=2 sw=2 et:
