#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

##
## Purpose:
## This class is to support building with cargo. It
## must be different than cargo.bbclass because Rust
## now builds with Cargo but cannot use cargo.bbclass
## due to dependencies and assumptions in cargo.bbclass
## that Rust & Cargo are already installed. So this
## is used by cargo.bbclass and Rust
##

# add crate fetch support
inherit rust-common

# Where we download our registry and dependencies to
export CARGO_HOME = "${WORKDIR}/cargo_home"

# The pkg-config-rs library used by cargo build scripts disables itself when
# cross compiling unless this is defined. We set up pkg-config appropriately
# for cross compilation, so tell it we know better than it.
export PKG_CONFIG_ALLOW_CROSS = "1"

# Don't instruct cargo to use crates downloaded by bitbake. Some rust packages,
# for example the rust compiler itself, come with their own vendored sources.
# Specifying two [source.crates-io] will not work.
CARGO_DISABLE_BITBAKE_VENDORING ?= "0"

# Used by libstd-rs to point to the vendor dir included in rustc src
CARGO_VENDORING_DIRECTORY ?= "${CARGO_HOME}/bitbake"

CARGO_RUST_TARGET_CCLD ?= "${RUST_TARGET_CCLD}"
cargo_common_do_configure () {
	mkdir -p ${CARGO_HOME}/bitbake

	cat <<- EOF > ${CARGO_HOME}/config
	# EXTRA_OECARGO_PATHS
	paths = [
	$(for p in ${EXTRA_OECARGO_PATHS}; do echo \"$p\",; done)
	]
	EOF

	cat <<- EOF >> ${CARGO_HOME}/config

	# Local mirror vendored by bitbake
	[source.bitbake]
	directory = "${CARGO_VENDORING_DIRECTORY}"
	EOF

	if [ ${CARGO_DISABLE_BITBAKE_VENDORING} = "0" ]; then
		cat <<- EOF >> ${CARGO_HOME}/config

		[source.crates-io]
		replace-with = "bitbake"
		local-registry = "/nonexistent"
		EOF
	fi

	cat <<- EOF >> ${CARGO_HOME}/config

	[http]
	# Multiplexing can't be enabled because http2 can't be enabled
	# in curl-native without dependency loops
	multiplexing = false

	# Ignore the hard coded and incorrect path to certificates
	cainfo = "${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt"

	EOF

	cat <<- EOF >> ${CARGO_HOME}/config

	# HOST_SYS
	[target.${RUST_HOST_SYS}]
	linker = "${CARGO_RUST_TARGET_CCLD}"
	EOF

	if [ "${RUST_HOST_SYS}" != "${RUST_BUILD_SYS}" ]; then
		cat <<- EOF >> ${CARGO_HOME}/config

		# BUILD_SYS
		[target.${RUST_BUILD_SYS}]
		linker = "${RUST_BUILD_CCLD}"
		EOF
	fi

	if [ "${RUST_TARGET_SYS}" != "${RUST_BUILD_SYS}" -a "${RUST_TARGET_SYS}" != "${RUST_HOST_SYS}" ]; then
		cat <<- EOF >> ${CARGO_HOME}/config

		# TARGET_SYS
		[target.${RUST_TARGET_SYS}]
		linker = "${RUST_TARGET_CCLD}"
		EOF
	fi

	# Put build output in build directory preferred by bitbake instead of
	# inside source directory unless they are the same
	if [ "${B}" != "${S}" ]; then
		cat <<- EOF >> ${CARGO_HOME}/config

		[build]
		# Use out of tree build destination to avoid polluting the source tree
		target-dir = "${B}/target"
		EOF
	fi

	cat <<- EOF >> ${CARGO_HOME}/config

	[term]
	progress.when = 'always'
	progress.width = 80
	EOF
}

python cargo_common_do_patch_paths() {
    import shutil

    cargo_config = os.path.join(d.getVar("CARGO_HOME"), "config")
    if not os.path.exists(cargo_config):
        return

    src_uri = (d.getVar('SRC_URI') or "").split()
    if len(src_uri) == 0:
        return

    patches = dict()
    workdir = d.getVar('WORKDIR')
    fetcher = bb.fetch2.Fetch(src_uri, d)
    for url in fetcher.urls:
        ud = fetcher.ud[url]
        if ud.type == 'git':
            name = ud.parm.get('name')
            destsuffix = ud.parm.get('destsuffix')
            if name is not None and destsuffix is not None:
                if ud.user:
                    repo = '%s://%s@%s%s' % (ud.proto, ud.user, ud.host, ud.path)
                else:
                    repo = '%s://%s%s' % (ud.proto, ud.host, ud.path)
                path = '%s = { path = "%s" }' % (name, os.path.join(workdir, destsuffix))
                patches.setdefault(repo, []).append(path)

    with open(cargo_config, "a+") as config:
        for k, v in patches.items():
            print('\n[patch."%s"]' % k, file=config)
            for name in v:
                print(name, file=config)

    if not patches:
        return

    # Cargo.lock file is needed for to be sure that artifacts
    # downloaded by the fetch steps are those expected by the
    # project and that the possible patches are correctly applied.
    # Moreover since we do not want any modification
    # of this file (for reproducibility purpose), we prevent it by
    # using --frozen flag (in CARGO_BUILD_FLAGS) and raise a clear error
    # here is better than letting cargo tell (in case the file is missing)
    # "Cargo.lock should be modified but --frozen was given"

    manifest_path = d.getVar("MANIFEST_PATH", True)
    lockfile = os.path.join(os.path.dirname(manifest_path), "Cargo.lock")
    if not os.path.exists(lockfile):
        bb.fatal(f"{lockfile} file doesn't exist")

    # There are patched files and so Cargo.lock should be modified but we use
    # --frozen so let's handle that modifications here.
    #
    # Note that a "better" (more elegant ?) would have been to use cargo update for
    # patched packages:
    #  cargo update --offline -p package_1 -p package_2
    # But this is not possible since it requires that cargo local git db
    # to be populated and this is not the case as we fetch git repo ourself.

    lockfile_orig = lockfile + ".orig"
    if not os.path.exists(lockfile_orig):
        shutil.copy(lockfile, lockfile_orig)

    newlines = []
    with open(lockfile_orig, "r") as f:
        for line in f.readlines():
            if not line.startswith("source = \"git"):
                newlines.append(line)

    with open(lockfile, "w") as f:
        f.writelines(newlines)
}
do_configure[postfuncs] += "cargo_common_do_patch_paths"

do_compile:prepend () {
        oe_cargo_fix_env
}

oe_cargo_fix_env () {
	export CC="${RUST_TARGET_CC}"
	export CXX="${RUST_TARGET_CXX}"
	export CFLAGS="${CFLAGS}"
	export CXXFLAGS="${CXXFLAGS}"
	export AR="${AR}"
	export TARGET_CC="${RUST_TARGET_CC}"
	export TARGET_CXX="${RUST_TARGET_CXX}"
	export TARGET_CFLAGS="${CFLAGS}"
	export TARGET_CXXFLAGS="${CXXFLAGS}"
	export TARGET_AR="${AR}"
	export HOST_CC="${RUST_BUILD_CC}"
	export HOST_CXX="${RUST_BUILD_CXX}"
	export HOST_CFLAGS="${BUILD_CFLAGS}"
	export HOST_CXXFLAGS="${BUILD_CXXFLAGS}"
	export HOST_AR="${BUILD_AR}"
}

EXTRA_OECARGO_PATHS ??= ""

EXPORT_FUNCTIONS do_configure

# The culprit for this setting is the libc crate,
# which as of Jun 2023 calls directly into 32 bit time functions in glibc,
# bypassing all of glibc provisions to choose the right Y2038-safe functions. As
# rust components statically link with that crate, pretty much everything
# is affected, and so there's no point trying to have recipe-specific
# INSANE_SKIP entries.
#
# Upstream ticket and PR:
# https://github.com/rust-lang/libc/issues/3223
# https://github.com/rust-lang/libc/pull/3175
INSANE_SKIP:append = " 32bit-time"
