# Copyright 2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

inherit desktop unpacker xdg

MY_PN="${PN/-bin/}"

DESCRIPTION="Claude Desktop - official AI assistant application for Linux"
HOMEPAGE="https://claude.ai"
# Official first-party .deb published by Anthropic via their APT repository.
SRC_URI="https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/${MY_PN}/${MY_PN}_${PV}_amd64.deb -> ${P}.deb"

S="${WORKDIR}"

LICENSE="all-rights-reserved"
SLOT="0"
KEYWORDS="-* ~amd64"
IUSE="+cowork gnome"
RESTRICT="mirror strip bindist"

# Mirrors the Depends/Recommends of the upstream .deb control file. Several
# of these libraries are dlopen()ed by Electron (libnotify, libsecret,
# libayatana-appindicator) and never show up in ldd output.
#
# Cowork runs the agent in a local KVM guest. app.asar (2.110.0) looks up
# qemu-system-x86_64 in PATH, virtiofsd in /usr/libexec then /usr/bin, and the
# UEFI firmware only in /usr/share/OVMF (see src_install).
RDEPEND="
	>=app-accessibility/at-spi2-core-2.46.0:2
	app-crypt/libsecret
	app-misc/ca-certificates
	dev-libs/expat
	dev-libs/glib:2
	dev-libs/libayatana-appindicator
	dev-libs/nspr
	dev-libs/nss
	media-libs/alsa-lib
	media-libs/mesa
	net-print/cups
	sys-apps/dbus
	sys-apps/util-linux
	sys-apps/xdg-desktop-portal
	virtual/libudev
	x11-libs/cairo
	x11-libs/gdk-pixbuf:2
	x11-libs/gtk+:3
	x11-libs/libdrm
	x11-libs/libnotify
	x11-libs/libX11
	x11-libs/libxcb
	x11-libs/libXcomposite
	x11-libs/libXdamage
	x11-libs/libXext
	x11-libs/libXfixes
	x11-libs/libxkbcommon
	x11-libs/libXrandr
	x11-libs/libXtst
	x11-libs/pango
	x11-misc/xdg-utils
	|| (
		sys-apps/xdg-desktop-portal-gtk
		sys-apps/xdg-desktop-portal-gnome
		kde-plasma/xdg-desktop-portal-kde
	)
	cowork? (
		app-emulation/qemu[qemu_softmmu_targets_x86_64]
		app-emulation/virtiofsd
		|| (
			sys-firmware/edk2-bin[qemu_softmmu_targets_x86_64(+)]
			sys-firmware/edk2
		)
	)
	gnome? ( dev-libs/gjs )
"

QA_PREBUILT="*"

src_install() {
	# Official .deb ships the app under usr/lib/claude-desktop/ (electron
	# launcher 'claude-desktop' + resources/app.asar). The Cowork pieces live
	# in resources/ too: smol-bin.x64.img (guest image), cowork-linux-helper
	# and a fallback virtiofsd. Nothing in app.asar hardcodes the install
	# prefix (it uses process.resourcesPath), so /opt is safe.
	mkdir -p "${ED}/opt/${MY_PN}" || die
	cp -r "${S}/usr/lib/${MY_PN}/"* "${ED}/opt/${MY_PN}" || die

	# Chrome sandbox: setuid root with restricted permissions (Electron pattern)
	if [[ -f "${ED}/opt/${MY_PN}/chrome-sandbox" ]]; then
		fperms 4755 "/opt/${MY_PN}/chrome-sandbox"
	fi

	if use cowork; then
		# The firmware candidates are Debian paths only:
		# /usr/share/OVMF/OVMF_CODE_4M.fd then /usr/share/OVMF/OVMF_CODE.fd,
		# with OVMF_VARS derived by name in the same directory. Both
		# sys-firmware/edk2 and sys-firmware/edk2-bin install the raw 2M
		# OVMF_CODE.fd/OVMF_VARS.fd pair in /usr/share/edk2/OvmfX64.
		dosym edk2/OvmfX64 /usr/share/OVMF
	fi

	# Wrapper script with Wayland and proxy support
	cat > "${T}/${MY_PN}" <<-'WRAPPER' || die
		#!/bin/bash
		INSTALL_DIR="/opt/claude-desktop"
		export ELECTRON_OZONE_PLATFORM_HINT="${ELECTRON_OZONE_PLATFORM_HINT:-auto}"

		# Proxy support
		PROXY_ARGS=""
		PROXY_URL="${https_proxy:-${HTTPS_PROXY:-${http_proxy:-${HTTP_PROXY:-}}}}"
		NO_PROXY_LIST="${no_proxy:-${NO_PROXY:-}}"
		if [ -n "$PROXY_URL" ]; then
		    PROXY_ARGS="--proxy-server=$PROXY_URL"
		    [ -n "$NO_PROXY_LIST" ] && PROXY_ARGS="$PROXY_ARGS --proxy-bypass-list=$NO_PROXY_LIST"
		fi

		exec "$INSTALL_DIR/claude-desktop" \
		    ${WAYLAND_DISPLAY:+--enable-features=WaylandWindowDecorations} \
		    $PROXY_ARGS "$@"
	WRAPPER
	dobin "${T}/${MY_PN}"

	# Official desktop file. Anthropic ships it as com.anthropic.Claude.desktop
	# (reverse-DNS id, not ${MY_PN}.desktop), and it declares
	# MimeType=x-scheme-handler/claude; which is the handler the browser needs
	# to hand the claude:// sign-in callback back to the app.
	# Exec=claude-desktop %U resolves to our wrapper on PATH. Install it
	# verbatim: make_desktop_entry would drop the MimeType and leave claude://
	# unregistered (xdg-open finds no handler, sign-in never completes).
	if [[ -f "${S}/usr/share/applications/com.anthropic.Claude.desktop" ]]; then
		domenu "${S}/usr/share/applications/com.anthropic.Claude.desktop"
	else
		die "upstream desktop file com.anthropic.Claude.desktop not found; upstream layout changed"
	fi

	# Icons (hicolor 16-256)
	local size icon_path
	for size in 16 32 48 128 256; do
		icon_path="${S}/usr/share/icons/hicolor/${size}x${size}/apps/${MY_PN}.png"
		if [[ -f "${icon_path}" ]]; then
			newicon -s ${size} "${icon_path}" ${MY_PN}.png
		fi
	done

	if use gnome; then
		# GNOME Shell search provider, registered by the Debian postinst.
		local sp="${ED}/opt/${MY_PN}/resources/gnome-search-provider"
		insinto /usr/share/gnome-shell/search-providers
		doins "${sp}/com.anthropic.Claude.search-provider.ini"
		sed -e "s|/usr/lib/${MY_PN}/|/opt/${MY_PN}/|" \
			"${sp}/com.anthropic.Claude.SearchProvider.service" \
			> "${T}/com.anthropic.Claude.SearchProvider.service" || die
		insinto /usr/share/dbus-1/services
		doins "${T}/com.anthropic.Claude.SearchProvider.service"
	fi
}

pkg_postinst() {
	xdg_pkg_postinst

	elog "Claude Desktop has been installed to /opt/${MY_PN}"
	elog ""
	elog "To launch: ${MY_PN}"
	elog ""
	elog "This is the official Anthropic Claude Desktop for Linux (beta)."
	elog "Voice dictation and computer use are not available on Linux yet."

	if use cowork; then
		elog ""
		elog "Cowork runs its agent in a local KVM guest. It needs:"
		elog "  - CONFIG_KVM (+ KVM_INTEL or KVM_AMD) and CONFIG_VHOST_VSOCK"
		elog "  - your user in the 'kvm' group (/dev/kvm and /dev/vhost-vsock)"
		elog "Logs: ~/.config/Claude/logs/cowork_vm_node.log"
		if has_version app-misc/claude-cowork-service-bin; then
			ewarn ""
			ewarn "app-misc/claude-cowork-service-bin is obsolete: Cowork is now"
			ewarn "native. Disable its user unit and unmerge it:"
			ewarn "  systemctl --user disable --now claude-cowork"
			ewarn "  emerge --ask --depclean app-misc/claude-cowork-service-bin"
		fi
	fi
}