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

EAPI=8

CRATES="
	adler2@2.0.1
	avt@0.17.0
	bytemuck@1.24.0
	cfg-if@1.0.4
	crc32fast@1.5.0
	equivalent@1.0.2
	flate2@1.1.9
	hashbrown@0.16.0
	heck@0.5.0
	indexmap@2.12.0
	inventory@0.3.21
	libloading@0.8.9
	miniz_oxide@0.8.9
	proc-macro2@1.0.103
	quote@1.0.41
	regex-lite@0.1.8
	rgb@0.8.52
	rustler@0.37.0
	rustler_codegen@0.37.0
	rustversion@1.0.22
	simd-adler32@0.3.8
	syn@2.0.108
	unicode-ident@1.0.20
	unicode-width@0.1.14
	windows-link@0.2.1
	zlib-rs@0.6.0
"

RUST_MIN_VER="1.82.0"

inherit cargo edo systemd

DISTFILES_URI="https://github.com/Tatsh/tatsh-overlay/releases/download/__distfiles__"
# Hex is a Mix archive that mix installs by downloading it, and mix cannot read
# a lock file full of :hex entries without it.
HEX_PV="2.5.1"

DESCRIPTION="Platform for hosting and sharing terminal session recordings."
HOMEPAGE="https://asciinema.org https://github.com/asciinema/asciinema-server"
# Mix and npm both resolve over the network, so the dependency trees are
# fetched ahead of time and shipped whole. The Rust crates come from CRATES.
SRC_URI="
	${CARGO_CRATE_URIS}
	${DISTFILES_URI}/hex-${HEX_PV}-mix-home.tar.xz
	${DISTFILES_URI}/${P}-deps.tar.xz
	${DISTFILES_URI}/${P}-node_modules.tar.xz
	https://github.com/asciinema/${PN}/archive/refs/tags/v${PV}.tar.gz
		-> ${P}.gh.tar.gz
"
S="${WORKDIR}/${PN}-${PV}"

# Apache-2.0 is upstream's own. The rest cover the crates linked into the
# three Rust NIFs under native/.
LICENSE="Apache-2.0 ISC MIT Unicode-3.0 ZLIB"
SLOT="0"
KEYWORDS="~amd64"

RDEPEND="
	acct-group/asciinema
	acct-user/asciinema
	dev-lang/elixir
	dev-lang/erlang
	dev-db/postgresql
"
BDEPEND="
	dev-lang/elixir
	dev-lang/erlang
	dev-util/esbuild:*
	dev-util/tailwindcss
"

PATCHES=(
	"${FILESDIR}/${P}-security-updates.patch"
	"${FILESDIR}/${P}-system-tooling.patch"
)

# The release is a self contained tree of beam files, so there is nothing for
# the usual QA checks to look at, and it keeps its own debug information.
QA_PREBUILT="usr/libexec/${PN}/.*"

src_unpack() {
	cargo_src_unpack
}

src_prepare() {
	default

	# The two vendored trees unpack at the top of WORKDIR; mix and the asset
	# build expect them inside the source tree.
	rm -rf deps assets/node_modules || die
	mv "${WORKDIR}/deps" deps || die
	mv "${WORKDIR}/node_modules" assets/node_modules || die
}

src_compile() {
	local -x MIX_ENV=prod
	# Neither tool may reach the network, and neither may write outside the
	# build directory.
	local -x HEX_OFFLINE=1
	local -x HEX_HOME="${T}/hex" MIX_HOME="${WORKDIR}/mix-home"
	local -x HOME="${T}"
	# dev-util/esbuild is slotted by version and installs esbuild-${PV} with no
	# unversioned symlink, so pick the newest one that is installed.
	local esbuild
	esbuild="$(find "${ESYSROOT}/usr/bin" -maxdepth 1 -name 'esbuild-*' -type f |
		sort -V | tail -n1)"
	[[ -x ${esbuild} ]] || die "no esbuild binary in ${ESYSROOT}/usr/bin"
	local -x ESBUILD_PATH="${esbuild}"
	local -x TAILWIND_PATH="${ESYSROOT}/usr/bin/tailwindcss"

	edo mix deps.compile --no-deps-check
	edo mix compile --no-deps-check
	edo mix assets.deploy
	edo mix release --no-deps-check
}

src_install() {
	# Copied rather than installed with doins, which drops the executable bit.
	# The release needs it on nine files, and not only the obvious ones: the
	# launchers in bin/, releases/*/elixir and releases/*/iex, which have no
	# extension, and two helper scripts under lib/*/priv.
	dodir "/usr/libexec/${PN}"
	cp -a "_build/prod/rel/asciinema/." "${ED}/usr/libexec/${PN}/" || die

	# The release ships a Windows launcher alongside the shell one.
	rm "${ED}/usr/libexec/${PN}/bin/asciinema.bat" || die

	# systemd reads EnvironmentFile as root before switching to User=, so the
	# secrets in here never need to be readable by the service account.
	insinto "/etc/${PN}"
	newins "${FILESDIR}/server.env" server.env
	fperms 0600 "/etc/${PN}/server.env"

	# StateDirectory= in the unit creates /var/lib/${PN} and gives it to the
	# service account on first start, so it is not shipped here.
	systemd_dounit "${FILESDIR}/${PN}.service"

	dodoc README.md
}

pkg_postinst() {
	elog "Before starting the service:"
	elog
	elog "  1. Create the database and role:"
	elog "       createuser asciinema"
	elog "       createdb -O asciinema asciinema"
	elog "  2. Put SECRET_KEY_BASE, DATABASE_URL and URL_HOST in"
	elog "       /etc/${PN}/server.env"
	elog "     Generate the secret with: openssl rand -base64 48"
	elog
	elog "The unit runs bin/migrate before bin/server, so the schema is"
	elog "created and updated for you."
	elog
	ewarn "Two of the locked dependencies carry published advisories that"
	ewarn "cannot be resolved by updating them:"
	ewarn
	ewarn "  cowlib 2.20.0 (EEF-CVE-2026-43966, -43969, -43971)"
	ewarn "    Header and cookie injection in the HTTP layer. No fixed"
	ewarn "    release exists; 2.20.0 is the newest published."
	ewarn "  earmark 1.4.49 (EEF-CVE-2026-48591)"
	ewarn "    Stored XSS through unescaped attribute values. The package is"
	ewarn "    retired. Rendered markdown is passed through"
	ewarn "    HtmlSanitizeEx.basic_html/1 here, which allowlists attributes,"
	ewarn "    so the path is mitigated."
	ewarn
	ewarn "Consider whether to expose this server directly to the internet."
}