#
# Copyright 2021 Google LLC
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#

# Check for EAPI 5+
case "${EAPI:-0}" in
0|1|2|3|4) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
5|6) inherit eapi7-ver ;;
7) ;;
esac

inherit cros-workon cros-kernel2 osreleased

#
# To control the module signing behavior developers can define
# the following variables in an ebuild file:
#
# COS_KERNEL_X509_GENKEY (mandatory) contains path to an OpenSSL
# configuration file used to generate signing keys/certificates
#
# COS_KERNEL_ROOT_CERT (optional) contains path to the list of
# system-wide trusted keys in PEM format
#

# add custom fragments here
COS_CONFIG_FRAGMENTS=(
)

CONFIG_FRAGMENTS=(
	${CONFIG_FRAGMENTS[@]}
	${COS_CONFIG_FRAGMENTS[@]}
)

# When "nofragments" flag is set, do not overlay kernel config
# with fragments and use the config file as-is
IUSE="gpu nofragments ${COS_CONFIG_FRAGMENTS[@]}"

# Describe custom fragments by defining a human-readable
# description and configuration fragment

# foo_desc="Enable FOOBAR support"
# foo_config="
# CONFIG_FOOBAR=y
# "

cos-kernel_src_prepare() {
	cros-kernel2_src_prepare
}

cos-kernel_src_configure() {
	# Provide a custom key configuration file, because otherwise the kernel
	# would auto-generate one.
	mkdir -p "$(cros-workon_get_build_dir)/certs"

	if ! [ -f "${COS_KERNEL_X509_GENKEY}" ]; then
		die "x509 config not found: '${COS_KERNEL_X509_GENKEY}'"
	fi
	cp -f "${COS_KERNEL_X509_GENKEY}" \
		"$(cros-workon_get_build_dir)/certs/x509.genkey" || die
	# The root key belongs to lakitu board.
	if [ -n "${COS_KERNEL_ROOT_CERT}" ]; then
		if ! [ -f "${COS_KERNEL_ROOT_CERT}" ]; then
			die "COS kernel root cert not found: '${COS_KERNEL_ROOT_CERT}'"
		fi
		cp -f "${COS_KERNEL_ROOT_CERT}" \
			"$(cros-workon_get_build_dir)/certs/trusted_key.pem" || die
	fi

	if use nofragments; then
		export CONFIG_FRAGMENTS=()
	fi
	cros-kernel2_src_configure
}

tar_kernel_source() {
	# Put kernel source tarball under /opt to avoid it gets
	# masked by INSTALL_MASK.
	local source_dir=opt/google/src
	dodir "${source_dir}"
	pushd "${D}/usr/src/${P}" || die
	tar --exclude="./build" -czf "${D}/${source_dir}/kernel-src.tar.gz" .
	popd || die
}

tar_kernel_headers() {
	einfo "Packaging kernel headers"
	# We do pretty much exactly what scripts/package/builddeb does.
	pushd "${D}/usr/src/${P}" || die
	(
		find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl
		find arch/*/include include scripts -type f -o -type l
		find "arch/$(tc-arch-kernel)" -name module.lds -o -name Kbuild.platforms -o -name Platform
		find "arch/$(tc-arch-kernel)" -name include -o -name scripts -type d | while IFS='' read -r line; do
			find "${line}" -type f
		done
	) > "${T}/hdrsrcfiles"
	popd || die

	pushd "$(cros-workon_get_build_dir)" || die
	{
		if cros_chkconfig_present STACK_VALIDATION; then
			find tools/objtool -type f -executable
		fi

		find "arch/$(tc-arch-kernel)/include" Module.symvers include scripts -type f

		if cros_chkconfig_present GCC_PLUGINS; then
			find scripts/gcc-plugins -name \*.so -o -name gcc-common.h
		fi
	} > "${T}/hdrobjfiles"
	popd || die

	local destdir="${T}/headers_tmp/usr/src/linux-headers-$(kernelrelease)"
	mkdir -p "${destdir}"
	tar -c -f - -C "${D}/usr/src/${P}" -T "${T}/hdrsrcfiles" | tar -xf - -C "${destdir}"
	tar -c -f - -C "$(cros-workon_get_build_dir)" -T "${T}/hdrobjfiles" | tar -xf - -C "${destdir}"
	rm "${T}/hdrsrcfiles" "${T}/hdrobjfiles"

	cp "$(cros-workon_get_build_dir)/.config" "${destdir}/.config"

	# We don't configure INSTALL_MASK to remove files in /opt, so export the
	# headers tarball through /opt.
	local source_dir=opt/google/src
	dodir "${source_dir}"
	pushd "${T}/headers_tmp" || die
	tar -czf "${D}/${source_dir}/kernel-headers.tgz" .
	popd || die
	rm -r "${T}/headers_tmp"
}

write_toolchain_env() {
	# Write the compiler info used for kernel compilation
	# in toolchain_env.
	local toolchain_env_dir=etc
	# Example for toolchain_env content:
	# CC=x86_64-cros-linux-gnu-clang
	# CXX=x86_64-cros-linux-gnu-clang++
	# The file will be deleted after copying data to BUILD_DIR artifact
	echo "CC=${CC}" > "${D}/${toolchain_env_dir}/toolchain_env"
	echo "CXX=${CXX}" >> "${D}/${toolchain_env_dir}/toolchain_env"
}

write_kernel_info() {
	# Write kernel information used for building kernel.
	local kernel_info_dir=etc
	# Example for kernel_info content:
	# URL=https://chromium.googlesource.com/chromiumos/third_party/kernel
	echo "URL=${CROS_WORKON_REPO}/${CROS_WORKON_PROJECT}" > "${D}/${kernel_info_dir}/kernel_info"
}

get_kernel_commit_id() {
	# Provide kernel commit id
	# VCSID variable is unconditionally set by the cros-workon eclass, and
	# is in the form of "<ebuild_revision>-<sha1>".
	echo "${VCSID##*-}"
}

write_kernel_commit() {
	# Write kernel commit information used for building kernel.
	local kernel_commit_dir=etc
	# Example for kernel_commit content:
	# c7ad6ff415b5a1e87f8333e2a63c7209e6efc1b2
	get_kernel_commit_id > "${D}/${kernel_commit_dir}/kernel_commit"
}

cos-kernel_src_install() {
	cros-kernel2_src_install

	do_osrelease_field "KERNEL_COMMIT_ID" "$(get_kernel_commit_id)"

	if use kernel_sources; then
		# Install kernel source and headers tarballs so they can be exported as
		# artifacts later.
		tar_kernel_source
		tar_kernel_headers
		# Install kernel compiler information
		write_toolchain_env
		# Install kernel source information
		write_kernel_info
		# Install kernel commit information
		write_kernel_commit
	fi
}
