#
# 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[@]} hardened"

# 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_allow_gnu_build_tools
	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
        # * -fstack-clash-protection inserts code to probe each page of the stack space
        # as it is allocated to protect from stack-clash style attacks.
        # * -D_FORTIFY_SOURCE=2 enables additional security features of the GNU libc when
        # calling memory and string handling functions.
	if use hardened; then
		export KCFLAGS="-fstack-clash-protection -D_FORTIFY_SOURCE=2"
	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 OBJTOOL || 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
}
