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

EAPI=8

# The vendored dependency set includes crates (e.g. iroh, used only by the
# not-yet-packaged cluster plugin) whose MSRV is 1.91.
RUST_MIN_VER="1.91"

inherit cargo shell-completion systemd

DESCRIPTION="Scan logs and take action, a faster successor to fail2ban"
HOMEPAGE="https://reaction.ppom.me https://framagit.org/ppom/reaction"
SRC_URI="
	https://framagit.org/ppom/reaction/-/archive/v${PV}/reaction-v${PV}.tar.gz -> ${P}.tar.gz
	https://cafarelli.fr/gentoo/${P}-crates.tar.xz
"
S="${WORKDIR}/${PN}-v${PV}"

LICENSE="AGPL-3"
# Dependent crate licenses
LICENSE+="
	0BSD Apache-2.0 Apache-2.0-with-LLVM-exceptions BSD-1 BSD-2 BSD
	Boost-1.0 CC0-1.0 CDLA-Permissive-2.0 GPL-2 ISC LGPL-2.1+ MIT MIT-0
	Unicode-3.0 Unlicense ZLIB
"
SLOT="0"
KEYWORDS="~amd64"
IUSE="munin"

# reaction shells out to the firewall tools selected in its configuration
# (iptables, nftables, ipset, ...), so there is no hard runtime dependency.
# The munin plugin needs munin-node and jq at runtime.
RDEPEND="munin? ( net-analyzer/munin app-misc/jq )"

# The test suite needs network access and live firewall privileges,
# neither of which is available in the sandbox.
RESTRICT="test"

src_unpack() {
	cargo_src_unpack

	# Since 2.7.0, upstream's Cargo.lock pulls jrsonnet-evaluator/jrsonnet-stdlib
	# and a patched ipset crate from git instead of crates.io. Our crates
	# tarball is a plain "cargo vendor" directory (not unpacked into
	# ${ECARGO_VENDOR}), including the vendor-config.toml that cargo vendor
	# generates for git sources, per:
	# https://wiki.gentoo.org/wiki/Writing_Rust_ebuilds#Using_a_vendor_tarball_in_an_ebuild
	ln -s "${WORKDIR}"/vendor "${S}"/vendor || die

	sed -i \
		-e '/\[source.crates-io\]/d' \
		-e '/replace-with = "gentoo"/d' \
		-e '/local-registry = "\/nonexistent"/d' \
		"${ECARGO_HOME}"/config.toml || die
	cat "${WORKDIR}"/vendor/vendor-config.toml >> "${ECARGO_HOME}"/config.toml || die
}

src_configure() {
	# Build only the core daemon. The optional plugins (nftables, ipset,
	# cluster, virtual) are not packaged yet.
	#
	# --frozen is required for "cargo install" in src_install: without it,
	# cargo tries to re-resolve the jrsonnet/ipset git dependencies (see
	# src_unpack) against the network before it will honor our vendored
	# source replacement, even though Cargo.lock already pins them.
	cargo_src_configure --bin reaction --frozen
}

src_install() {
	cargo_src_install

	local tdir
	tdir=$(cargo_target_dir)

	# Man pages and shell completions are generated by build.rs, but only
	# during a release build.
	if [[ -f ${tdir}/reaction.1 ]]; then
		doman "${tdir}"/reaction*.1
	fi
	if [[ -f ${tdir}/reaction.bash ]]; then
		newbashcomp "${tdir}"/reaction.bash reaction
	fi
	if [[ -f ${tdir}/reaction.fish ]]; then
		dofishcomp "${tdir}"/reaction.fish
	fi
	if [[ -f ${tdir}/_reaction ]]; then
		dozshcomp "${tdir}"/_reaction
	fi

	newinitd "${FILESDIR}"/reaction.initd reaction
	newconfd "${FILESDIR}"/reaction.confd reaction

	insinto /etc/logrotate.d
	newins "${FILESDIR}"/reaction.logrotated reaction

	systemd_dounit packaging/reaction.service
	systemd_dounit packaging/system-reaction.slice

	if use munin; then
		exeinto /usr/libexec/munin/plugins
		newexe "${FILESDIR}"/reaction.munin reaction
		insinto /etc/munin/plugin-conf.d
		newins "${FILESDIR}"/reaction.munin-conf reaction
	fi

	keepdir /etc/reaction
	keepdir /var/lib/reaction

	dodoc README.md
	docinto examples
	dodoc config/example.yml config/example.jsonnet
}