# Copyright 2023-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v3

EAPI=8

KERNEL_IUSE_GENERIC_UKI=1

inherit kernel-install toolchain-funcs

# CachyOS source package is at pkgrel 1; the LTS binary pkgrel follows the
# Gentoo revision (6.18.55-r1 -> pkgrel 2).
CACHYOS_BIN_PR="$(( ${PR#r} + 1 ))"

# CachyOS pre-patched source tarball (needed for modules_prepare)
CACHYOS_SOURCE_PR="1"
MY_P="cachyos-$(ver_cut 1-3)-${CACHYOS_SOURCE_PR}"

# Binary package version string: {pkgver}-{pkgrel}
BINPKG_VER="${PV}-${CACHYOS_BIN_PR}"

# Mirror base URLs
MIRROR_V3="https://mirror.cachyos.org/repo/x86_64_v3/cachyos-v3"

DESCRIPTION="Pre-built CachyOS Linux LTS kernel"
HOMEPAGE="
	https://github.com/CachyOS/linux-cachyos
	https://github.com/Szowisz/CachyOS-kernels
"

# Source tarball (shared by all variants, needed for modules_prepare)
SRC_URI="
	https://github.com/CachyOS/linux/releases/download/${MY_P}/${MY_P}.tar.gz
"

# Binary packages per variant (x86_64_v3 only for this version)
# 6.18.55 LTS only: linux-cachyos-lts (no scheduler variants, no lto)
SRC_URI+="
	lts? (
		${MIRROR_V3}/linux-cachyos-lts-${BINPKG_VER}-x86_64_v3.pkg.tar.zst
		${MIRROR_V3}/linux-cachyos-lts-headers-${BINPKG_VER}-x86_64_v3.pkg.tar.zst
	)
"

S="${WORKDIR}"

LICENSE="GPL-2"
KEYWORDS="~amd64"
IUSE="+lts debug"
REQUIRED_USE="^^ ( lts )"

RDEPEND="
	!sys-kernel/cachyos-kernel:${SLOT}
"
BDEPEND="
	app-alternatives/bc
	app-alternatives/lex
	dev-util/pahole
	virtual/libelf
	app-alternatives/yacc
"
PDEPEND="
	>=virtual/dist-kernel-${PV}
"

QA_PREBUILT='*'

_cachyos_variant_suffix() {
	echo "cachyos-lts"
}

_cachyos_bin_distfile() {
	echo "linux-cachyos-lts-${BINPKG_VER}-x86_64_v3.pkg.tar.zst"
}

_cachyos_headers_distfile() {
	echo "linux-cachyos-lts-headers-${BINPKG_VER}-x86_64_v3.pkg.tar.zst"
}

_cachyos_setup_kv() {
	local suffix=$(_cachyos_variant_suffix)
	KV_LOCALVERSION="-${CACHYOS_BIN_PR}-${suffix}"
	KV_FULL="${PV}${KV_LOCALVERSION}"
}

pkg_setup() {
	_cachyos_setup_kv
}

src_unpack() {
	unpack "${MY_P}.tar.gz"

	mkdir -p "${WORKDIR}/binpkg" || die
	tar -C "${WORKDIR}/binpkg" -xf "${DISTDIR}/$(_cachyos_bin_distfile)" || die

	mkdir -p "${WORKDIR}/headerspkg" || die
	tar -C "${WORKDIR}/headerspkg" -xf "${DISTDIR}/$(_cachyos_headers_distfile)" || die
}

src_prepare() {
	_cachyos_setup_kv

	cd "${WORKDIR}/${MY_P}" || die

	echo "-${CACHYOS_BIN_PR}" > localversion.10-pkgrel || die
	echo "-$(_cachyos_variant_suffix)" > localversion.20-pkgname || die

	default
}

src_configure() {
	_cachyos_setup_kv

	local headers_build="${WORKDIR}/headerspkg/usr/lib/modules/${KV_FULL}/build"
	# Headers must match the binary exactly; never fall back to another release.
	[[ -d ${headers_build} ]] ||
		die "Cannot find exact-match headers build directory: ${headers_build}"

	# Generated build files must use the compiler that built the mirrored kernel.
	grep -qx 'CONFIG_CC_IS_GCC=y' "${headers_build}/.config" ||
		die "Mirrored LTS headers were not built with GCC; update the toolchain"

	local HOSTLD="$(tc-getBUILD_LD)"
	if type -P "${HOSTLD}.bfd" &>/dev/null; then
		HOSTLD+=.bfd
	fi
	local LD="$(tc-getLD)"
	if type -P "${LD}.bfd" &>/dev/null; then
		LD+=.bfd
	fi

	tc-export_build_env
	local makeargs=(
		V=1
		WERROR=0
		HOSTCC="$(tc-getBUILD_CC)"
		HOSTCXX="$(tc-getBUILD_CXX)"
		HOSTLD="${HOSTLD}"
		HOSTAR="$(tc-getBUILD_AR)"
		HOSTCFLAGS="${BUILD_CFLAGS}"
		HOSTLDFLAGS="${BUILD_LDFLAGS}"
		ARCH="$(tc-arch-kernel)"
		O="${WORKDIR}/modprep"
	)

	# The mirrored LTS kernel is built with GCC and BFD without LTO.
	makeargs+=(
		CROSS_COMPILE=${CHOST}-
		AS="$(tc-getAS)"
		CC="$(tc-getCC)"
		LD="${LD}"
		AR="$(tc-getAR)"
		NM="$(tc-getNM)"
		STRIP="$(tc-getSTRIP)"
		OBJCOPY="$(tc-getOBJCOPY)"
		OBJDUMP="$(tc-getOBJDUMP)"
		READELF="$(tc-getREADELF)"
	)

	mkdir "${WORKDIR}/modprep" || die
	cp "${headers_build}/.config" "${WORKDIR}/modprep/" || die

	emake -C "${WORKDIR}/${MY_P}" "${makeargs[@]}" modules_prepare
}

src_test() {
	_cachyos_setup_kv

	local binpkg_modules="${WORKDIR}/binpkg/usr/lib/modules/${KV_FULL}"
	local headers_build="${WORKDIR}/headerspkg/usr/lib/modules/${KV_FULL}/build"

	kernel-install_test "${KV_FULL}" \
		"${binpkg_modules}/vmlinuz" \
		"${binpkg_modules}" \
		"${headers_build}/.config"
}

src_install() {
	_cachyos_setup_kv

	local rel_kernel_dir="/usr/src/linux-${KV_FULL}"
	local binpkg_modules="${WORKDIR}/binpkg/usr/lib/modules/${KV_FULL}"
	local headers_build="${WORKDIR}/headerspkg/usr/lib/modules/${KV_FULL}/build"

	dodir "/lib/modules/${KV_FULL}"
	local f
	for f in "${binpkg_modules}"/*; do
		local fname="${f##*/}"
		[[ "${fname}" == "build" || "${fname}" == "source" ]] && continue
		[[ "${fname}" == "vmlinuz" ]] && continue
		[[ "${fname}" == "pkgbase" ]] && continue
		cp -a "${f}" "${ED}/lib/modules/${KV_FULL}/" || die
	done

	dosym "../../../src/linux-${KV_FULL}" "/lib/modules/${KV_FULL}/build"
	dosym "../../../src/linux-${KV_FULL}" "/lib/modules/${KV_FULL}/source"

	dodir "${rel_kernel_dir}"

	# Install exact-match headers before overlaying locally prepared build tools.
	cp -p -R "${headers_build}/." "${ED}${rel_kernel_dir}/" || die

	insinto "${rel_kernel_dir}/arch/x86/boot"
	newins "${binpkg_modules}/vmlinuz" bzImage

	insinto "${rel_kernel_dir}"
	doins "${headers_build}/System.map"
	doins "${headers_build}/.config"

	if [[ -f "${headers_build}/vmlinux" ]]; then
		doins "${headers_build}/vmlinux"
	fi

	find "${WORKDIR}/modprep" -type f '(' \
			-name Makefile -o \
			-name '*.[ao]' -o \
			-name '.*' \
		')' -delete || die
	# Keep upstream Kconfig output; local syncconfig rewrites it for this host.
	rm -rf "${WORKDIR}/modprep/include/config" \
		"${WORKDIR}"/modprep/include/generated/{autoconf.h,compile.h,rustc_cfg} || die
	rm -f "${WORKDIR}/modprep/source" 2>/dev/null
	cp -p -R "${WORKDIR}/modprep/." "${ED}${rel_kernel_dir}/" || die

	echo "${CATEGORY}/${PF}:${SLOT}" > "${ED}${rel_kernel_dir}/dist-kernel" || die

	find "${ED}/lib" -name '*.ko' -o -name '*.ko.zst' -exec touch {} + 2>/dev/null || true

	dostrip -x /lib/modules
	# Upstream modules are already compressed; an empty compressor run reads stdin.
	if [[ -n $(find "${ED}/lib/modules/${KV_FULL}" -name '*.ko' -print -quit) ]]; then
		kernel-install_compress_modules
	fi

	if use debug; then
		dostrip -x "${rel_kernel_dir}/vmlinux"
	fi
}

pkg_preinst() {
	_cachyos_setup_kv
	kernel-install_pkg_preinst
}

pkg_postinst() {
	_cachyos_setup_kv
	depmod "${KV_FULL}"
	kernel-install_pkg_postinst

	ewarn ""
	ewarn "${PN} is a pre-built CachyOS kernel from CachyOS mirrors."
	ewarn "${PN} is *not* supported by the Gentoo Kernel Project in any way."
	ewarn "Report ebuild and kernel problems to https://github.com/Szowisz/CachyOS-kernels."
	ewarn "Report kernel problems to the CachyOS project, if you sure it's due to upstream."
	ewarn "Do *not* open bugs in Gentoo's bugzilla. Thank you."
	ewarn ""
	ewarn "This kernel is built for x86-64-v3 (requires AVX2)."
	ewarn "If your CPU does not support x86-64-v3, use sys-kernel/cachyos-kernel instead."
	ewarn ""
}

pkg_postrm() {
	_cachyos_setup_kv
	kernel-install_pkg_postrm
}