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

EAPI=8

# conan-center-index's lzo/2.10 recipe fetches straight from
# oberhumer.com's own tiny personal mirror at conan-install time, which
# routinely answers real, fully-connected HTTP requests with a bare
# "501 Not Implemented" (reproduced directly with the same request Conan
# makes; not a DNS/connectivity problem, the one-person server itself is
# just unreliable). Conan's "sources backup cache" feature lets us hand it
# this file locally, keyed by the sha256 its own conandata.yml already
# expects, which skips that flaky request entirely -- see src_unpack/
# src_configure. Pinned to lzo/2.10's one known conandata.yml entry.
LZO_SHA256="c0f892943208266f9b6543b3ae308fab6284c5c90e627931446fb49b4221a072"

inherit cmake desktop git-r3 systemd xdg

DESCRIPTION="VPN client that resists DPI detection and censorship"
HOMEPAGE="https://amnezia.org"

EGIT_REPO_URI="https://github.com/amnezia-vpn/amnezia-client.git"
EGIT_BRANCH="dev"
# Only the two submodules actually needed on Linux: amneziawg-apple and
# qtgamepad are Apple/mobile-only and aren't touched by this build.
EGIT_SUBMODULES=( "client/3rd/qtkeychain" "client/3rd/SortFilterProxyModel" )

SRC_URI="http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz"

LICENSE="GPL-3"
SLOT="0"
KEYWORDS=""

# Upstream's build system drives Conan from CMakeLists.txt (conan_provider.cmake)
# to fetch/build 3rd-party deps (openssl, zlib, lz4, ...) that aren't vendored
# in the tarball. This needs network access during src_configure/src_compile,
# which Portage blocks by default under FEATURES=network-sandbox.
RESTRICT="network-sandbox"

DEPEND="
	dev-qt/qtbase:6[concurrent,dbus,gui,network,widgets,wayland,xml]
	dev-qt/qt5compat:6
	dev-qt/qtdeclarative:6
	dev-qt/qthttpserver:6
	dev-qt/qtremoteobjects:6
	dev-qt/qtsvg:6
	dev-qt/qttools:6
	dev-qt/qtwayland:6
"
RDEPEND="${DEPEND}
	dev-qt/qtshadertools:6
"
BDEPEND="
	dev-util/conan
	dev-qt/qttools:6
"

src_unpack() {
	# git itself links against the same libcurl as `curl`/cmd/go -- built on
	# this host with the c-ares resolver, which (like them) bypasses NSS and
	# queries /etc/resolv.conf's nameserver directly instead of going through
	# systemd-resolved. See the go-connect-proxy.py comment in src_configure
	# for the full story; the same tiny local CONNECT proxy fixes git's own
	# https:// fetch here, for the same reason.
	local go_proxy_fifo="${T}/go-connect-proxy.port"
	mkfifo "${go_proxy_fifo}" || die "mkfifo failed"
	python3 "${FILESDIR}/go-connect-proxy.py" 0 > "${go_proxy_fifo}" &
	local go_proxy_pid=$!
	local go_proxy_port
	go_proxy_port=$(timeout 5 cat "${go_proxy_fifo}")
	rm -f "${go_proxy_fifo}"
	[[ -n ${go_proxy_port} ]] || die "go-connect-proxy failed to start"

	http_proxy="http://127.0.0.1:${go_proxy_port}" \
	https_proxy="http://127.0.0.1:${go_proxy_port}" \
		git-r3_src_unpack
	local ret=$?
	kill "${go_proxy_pid}" 2>/dev/null
	[[ ${ret} -eq 0 ]] || die "git-r3_src_unpack failed"

	# Seed Conan's local sources backup cache (see LZO_SHA256 above) so its
	# own conan-center-index recipe never has to touch oberhumer.com itself.
	# (The tarball only needs to exist in DISTDIR, not be unpacked here.)
	mkdir -p "${WORKDIR}/conan-sources-cache/s" || die
	cp "${DISTDIR}/lzo-2.10.tar.gz" \
		"${WORKDIR}/conan-sources-cache/s/${LZO_SHA256}" || die
}

src_configure() {
	conan profile detect --force || die "conan profile detect failed"
	conan remote add amnezia \
		"https://artifactory.amnezia.org/artifactory/api/conan/client-prebuilts" \
		--force || die "conan remote add failed"

	# Upstream's root conanfile.py uses the CMakeConfigDeps generator, which is
	# still gated behind an incubating conf in this Conan release.
	echo "tools.cmake.cmakedeps:new=will_break_next" \
		>> "$(conan config home)/global.conf" || die "failed to enable CMakeConfigDeps conf"

	# See LZO_SHA256/src_unpack above.
	echo "core.sources:download_cache=${WORKDIR}/conan-sources-cache" \
		>> "$(conan config home)/global.conf" || die "failed to enable sources download cache conf"

	# Conan 2.24's bundled settings.yml only knows compilers up to
	# gcc 15 / clang 21; conan profile detect and conan_provider.cmake
	# record the real major (gcc 16 / clang 23) and Conan rejects it:
	#   ERROR: Invalid setting '23' is not a valid
	#          'settings.compiler.version' value.
	# settings_user.yml is merged on top of settings.yml, so extend the
	# accepted version lists. ${HOME} is ${PORTAGE_BUILDDIR}/homedir
	# (fresh per build), so rewrite it every configure.
	local conan_home
	conan_home="$(conan config home)" || die "conan config home failed"
	cat > "${conan_home}/settings_user.yml" <<-EOF || die "failed to write settings_user.yml"
		compiler:
		    gcc:
		        version: ["16", "16.1", "16.2"]
		    clang:
		        version: ["22", "23"]
	EOF

	local mycmakeargs=(
		-DCMAKE_BUILD_TYPE=Release
		-DCMAKE_INSTALL_PREFIX=/opt/AmneziaVPN
	)

	# conan_provider.cmake's conan install (above) builds amnezia-xray-bindings
	# locally, which runs `go build` against an un-vendored go.mod -- `go`
	# fetches github.com/amnezia-vpn/amnezia-xray-core straight from
	# proxy.golang.org. cmd/go's own hostname resolution is *always* pure-Go
	# (the go tool binary itself is built without cgo support, even when
	# CGO_ENABLED=1 is the default for code it compiles -- GODEBUG=netdns=cgo
	# is silently ignored for it), so on a host where /etc/resolv.conf's
	# nameserver is a LAN router rather than the local systemd-resolved stub
	# and a firewall only allows that stub to speak raw DNS, go's direct UDP
	# query gets rejected and fails every later write on that socket with
	# EPERM. go's HTTP client does honor https_proxy/http_proxy though, and a
	# CONNECT tunnel only requires go to resolve the proxy's own (literal,
	# DNS-free) address -- the real target host gets resolved by the proxy
	# process instead, via Python's normal glibc/NSS path, which isn't
	# affected by this. Spin up the tiny local one from files/ for the
	# duration of this configure (it's where conan's build-missing step
	# runs), and tear it down again right after.
	local go_proxy_fifo="${T}/go-connect-proxy.port"
	mkfifo "${go_proxy_fifo}" || die "mkfifo failed"
	python3 "${FILESDIR}/go-connect-proxy.py" 0 > "${go_proxy_fifo}" &
	local go_proxy_pid=$!
	local go_proxy_port
	go_proxy_port=$(timeout 5 cat "${go_proxy_fifo}")
	rm -f "${go_proxy_fifo}"
	[[ -n ${go_proxy_port} ]] || die "go-connect-proxy failed to start"

	http_proxy="http://127.0.0.1:${go_proxy_port}" \
	https_proxy="http://127.0.0.1:${go_proxy_port}" \
		cmake_src_configure
	local ret=$?
	kill "${go_proxy_pid}" 2>/dev/null
	[[ ${ret} -eq 0 ]] || die "cmake failed"
}

src_install() {
	cmake_src_install

	# Upstream's Qt deploy step bundles the auxiliary Wayland integration
	# plugins (decoration/shell/graphics) but not the actual "wayland" QPA
	# platform plugin itself, so the self-contained bundle can only run
	# under X11/xcb and fails under a native Wayland session with:
	#   Could not find the Qt platform plugin "wayland" in ""
	# Copy it in directly from the system's qtbase (built with USE=wayland).
	insinto /opt/AmneziaVPN/lib64/qt6/plugins/platforms
	doins "${EPREFIX}"/usr/lib64/qt6/plugins/platforms/libqwayland.so

	doicon "${S}/deploy/data/linux/AmneziaVPN.png"
	# make_desktop_entry's first arg becomes both Exec= and TryExec=; a bare
	# command name isn't on $PATH (the binary only lives under
	# /opt/AmneziaVPN/bin/), so desktop environments that check TryExec
	# before showing an entry hide it entirely. Use the full path.
	make_desktop_entry /opt/AmneziaVPN/bin/AmneziaVPN "Amnezia VPN" AmneziaVPN "Network;VPN"

	systemd_dounit "${S}/deploy/data/linux/AmneziaVPN.service"
}