# Maintainer: Duncan Tourolle <duncan@tourolle.paris>
#
# Builds from the local checkout rather than a release tarball, which is what
# makes `makepkg -si` in this directory install what you are actually working
# on. Swap `source` for a tagged tarball when there is something to release.
pkgname=darkroom
pkgver=0.23.0
# Back to 1 with the version: a new pkgver is a new archive name, so there is
# nothing for makepkg to reuse and nothing for a release number to disambiguate.
pkgrel=1
pkgdesc="Non-destructive RAW photo library and editor"
arch=('x86_64')
url="https://gitea.tourolle.paris/dtourolle/DarkRoom"
license=('GPL-3.0-or-later')
# Runtime: Vulkan for wgpu, and a Secret Service implementation for the
# Nextcloud credentials (FR-NC-2) — gnome-keyring or kwallet both provide it.
depends=('vulkan-icd-loader' 'fontconfig' 'libxkbcommon')
makedepends=('cargo' 'git' 'curl' 'unzip')
# Two ONNX Runtime builds ship in /usr/lib/darkroom/runtimes — Intel's
# OpenVINO build and the generic WebGPU one, both 8–10× the built-in tract
# on the CPU alone — and the app opens every runtime it finds and keeps the
# one that fits the GPU (docs/dev/inference.md §3.2). The ROCm build in
# /usr/lib adds the MIGraphX rung on an AMD GPU and outranks both there;
# Intel's OpenCL driver is what lets OpenVINO reach an Intel GPU.
optdepends=('gnome-keyring: store Nextcloud credentials'
            'kwallet: store Nextcloud credentials'
            'onnxruntime-rocm: run the neural models on an AMD GPU'
            'intel-compute-runtime: run the neural models on an Intel GPU')
options=('!lto')  # the workspace sets its own LTO in Cargo.toml

_repo="$(cd "${startdir}/.." && pwd)"

build() {
    cd "${_repo}"
    export RUSTUP_TOOLCHAIN=stable
    export CARGO_TARGET_DIR="${_repo}/target"
    cargo build --release --locked -p darkroom-desktop
}

package() {
    cd "${_repo}"
    install -Dm755 "target/release/darkroom-desktop" \
        "${pkgdir}/usr/bin/darkroom-desktop"

    install -Dm644 "packaging/paris.tourolle.darkroom.desktop" \
        "${pkgdir}/usr/share/applications/paris.tourolle.darkroom.desktop"

    # The same AppStream file the Flatpak installs, so a software centre
    # describes the two packages identically instead of falling back to the
    # desktop entry's one-line Comment for this one. Installed here rather than
    # written twice: the description, the licence fields and the OARS rating
    # are facts about the application, not about how it was packaged.
    install -Dm644 "packaging/paris.tourolle.darkroom.metainfo.xml" \
        "${pkgdir}/usr/share/metainfo/paris.tourolle.darkroom.metainfo.xml"

    # The icon's *name* is the contract, not its path: the desktop entry says
    # `Icon=paris.tourolle.darkroom` and the compositor resolves that through
    # the hicolor theme. Installed under 256x256 because that is the source's
    # actual size — lying about it makes scaled-down icons look wrong.
    install -Dm644 "ui/dr-ui/ui/app-icon.png" \
        "${pkgdir}/usr/share/icons/hicolor/256x256/apps/paris.tourolle.darkroom.png"

    install -Dm644 "README.md" "${pkgdir}/usr/share/doc/${pkgname}/README.md"

    # The bundled runtimes, where darkroom-desktop's search finds them
    # (`runtimes/` under /usr/lib/darkroom). Pinned wheels, checked by hash.
    ./tools/fetch-bundled-runtimes.sh linux "${pkgdir}/usr/lib/darkroom/runtimes"

    # The manual: the rendered page and its pictures, where the app's Help
    # opens it (dr_ui::manual, through dr_plat::system_data_dirs). Offline by
    # design — the help sheet's "See it" links land here, on a machine that
    # may have no network. The pictures are in LFS like the models, and a
    # pointer shipped in their place is a manual of broken images, so the
    # same refusal applies.
    install -Dm644 "docs/manual/index.html" "${pkgdir}/usr/share/darkroom/manual/index.html"
    for _f in docs/manual/media/*; do
        if head -c 40 "${_f}" | grep -q '^version https://git-lfs'; then
            echo "error: $(basename "${_f}") is an LFS pointer, not a picture — run: git lfs pull" >&2
            return 1
        fi
        install -Dm644 "${_f}" "${pkgdir}/usr/share/darkroom/manual/media/$(basename "${_f}")"
    done

    # The face models, into the last directory the app searches. A pair the
    # user placed in their own data directory outranks these, so installing
    # them cannot override a deliberate choice of weights.
    #
    # These live in LFS; a checkout without `git lfs pull` has ~130-byte
    # pointers here. Installing one produces a package whose face indexing
    # fails inside the graph loader on the user's machine, so refuse instead.
    #
    # The last three are the eye-state models (docs/dev/faces.md §17): landmarks,
    # open/closed, sunglasses. Optional to the app, which indexes without
    # them, but shipped beside the pair so the eyes-open filter works out of
    # the box.
    for _m in scrfd_500m_640.onnx scrfd_2.5g_640.onnx scrfd_10g_640.onnx arcface_mbf_b1.onnx \
              2d106det_b1.onnx ocec_s_b1.onnx sgc_l_48_b1.onnx; do
        _src="models/face/${_m}"
        if [[ "$(stat -c%s "${_src}")" -lt 100000 ]]; then
            echo "error: ${_m} is an LFS pointer, not a model — run: git lfs pull" >&2
            return 1
        fi
        install -Dm644 "${_src}" "${pkgdir}/usr/share/darkroom/models/${_m}"
    done

    # The scene model, for the per-category grades. Unlike the face weights
    # this one is in the repository — AGPL, and GPLv3 §13 permits the
    # combination (models/LICENCE.md) — so it is installed unconditionally and
    # a pointer here is a broken checkout rather than a licence decision.
    #
    # Three files: the graph, its vocabulary, and the category descriptor
    # grouping ADE20K's 150 classes into what the tab shows. All three, because
    # dr_ui::library::scene_model reports the tab unavailable without any one
    # of them. Only the graph gets the pointer check — the other two are
    # legitimately a few kilobytes.
    _src="models/scene/yolo26s-sem-ade20k.onnx"
    if [[ "$(stat -c%s "${_src}")" -lt 100000 ]]; then
        echo "error: the scene model is an LFS pointer — run: git lfs pull" >&2
        return 1
    fi
    for _m in yolo26s-sem-ade20k.onnx yolo26s-sem-ade20k.classes.json categories.txt; do
        install -Dm644 "models/scene/${_m}" "${pkgdir}/usr/share/darkroom/models/${_m}"
    done

    # The panorama border filler (MI-GAN, MIT — models/LICENCE.md). Same
    # pointer check as the scene model, same directory, same reason.
    _src="models/inpaint/migan-512.onnx"
    if [[ "$(stat -c%s "${_src}")" -lt 100000 ]]; then
        echo "error: the inpainting model is an LFS pointer — run: git lfs pull" >&2
        return 1
    fi
    install -Dm644 "${_src}" "${pkgdir}/usr/share/darkroom/models/migan-512.onnx"

    # The learned demosaic and denoise, one network per method (the project's
    # own weights, GPL — models/LICENCE.md). Same pointer check, same
    # directory.
    for _net in fast medium best; do
        _src="models/denoise/mosaic-${_net}-1408.onnx"
        if [[ "$(stat -c%s "${_src}")" -lt 100000 ]]; then
            echo "error: the ${_net} denoise model is an LFS pointer — run: git lfs pull" >&2
            return 1
        fi
        install -Dm644 "${_src}" "${pkgdir}/usr/share/darkroom/models/mosaic-${_net}-1408.onnx"
    done
}
