#
## Copyright (C) 2019 Wind River Systems, Inc.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

RPM_POSTPROCESS_COMMANDS_append = "wrl_installer;"
do_rootfs[vardeps] += "INSTALLER_TARGET_BUILD INSTALLER_TARGET_IMAGE"

# Fix system-shutdown hang at ratelimiting
APPEND_append = " printk.devkmsg=on"

INSTPRODUCT ?= "${DISTRO_NAME}"
INSTVER     ?= "${DISTRO_VERSION}"
INSTBUGURL  ?= "http://www.windriver.com/"

# NOTE: Please update anaconda-init when you change INSTALLER_CONFDIR, use "="
#       but not "?=" since this is not configurable.
INSTALLER_CONFDIR = "${IMAGE_ROOTFS}/installer-config"
KICKSTART_FILE ??= ""
KICKSTART_FILE_EXTRA ??= ""
WRL_INSTALLER_CONF ?= ""
REPO_EXCLUDE_PKG ?= ""

build_iso_prepend() {
	install -d ${ISODIR}
	ln -snf /.discinfo ${ISODIR}/.discinfo
	ln -snf /.buildstamp ${ISODIR}/.buildstamp
	ln -snf /Packages ${ISODIR}/Packages
}

build_iso_append() {
	implantisomd5 ${IMGDEPLOYDIR}/${IMAGE_NAME}.iso
}

# Check WRL_INSTALLER_CONF and copy it to
# ${IMAGE_ROOTFS}/.buildstamp.$prj_name when exists
wrl_installer_copy_buildstamp() {
    prj_name=$1
    buildstamp=$2
    if [ -f $buildstamp ]; then
        bbnote "Using $buildstamp as the buildstamp"
        cp $buildstamp ${IMAGE_ROOTFS}/.buildstamp.$prj_name
    else
        bbfatal "Can't find WRL_INSTALLER_CONF: $buildstamp"
    fi
}

# Hardlink when possible, otherwise copy.
# $1: src
# $2: target
wrl_installer_hardlinktree() {
    src_dev="`stat -c %d $1`"
    if [ -e "$2" ]; then
        tgt_dev="`stat -c %d $2`"
    else
        tgt_dev="`stat -c %d $(dirname $2)`"
    fi
    hdlink=""
    if [ "$src_dev" = "$tgt_dev" ]; then
        hdlink="--link"
    fi
    cp -rvf $hdlink $1 $2
}

wrl_installer_copy_local_repos() {
    deploy_dir_rpm=$1

    if [ -d "$deploy_dir_rpm" ]; then
        echo "Copy rpms from target build to installer image."
        mkdir -p ${IMAGE_ROOTFS}/Packages.$prj_name

        : > ${IMAGE_ROOTFS}/Packages.$prj_name/.treeinfo
        echo "[general]" >> ${IMAGE_ROOTFS}/Packages.$prj_name/.treeinfo
        echo "version = ${DISTRO_VERSION}" >> ${IMAGE_ROOTFS}/Packages.$prj_name/.treeinfo

        # Determine the max channel priority
        channel_priority=5
        for pt in $installer_target_archs ; do
            channel_priority=$(expr $channel_priority + 5)
        done

        : > ${IMAGE_ROOTFS}/Packages.$prj_name/.feedpriority
        for arch in $installer_target_archs; do
            if [ -d "$deploy_dir_rpm/"$arch -a ! -d "${IMAGE_ROOTFS}/Packages.$prj_name/"$arch ]; then
                channel_priority=$(expr $channel_priority - 5)
                echo "$channel_priority $arch" >> ${IMAGE_ROOTFS}/Packages.$prj_name/.feedpriority
                wrl_installer_hardlinktree "$deploy_dir_rpm/"$arch "${IMAGE_ROOTFS}/Packages.$prj_name/."
            fi
        done

        for pkg in ${REPO_EXCLUDE_PKG}; do
            rm -rf ${IMAGE_ROOTFS}/Packages.$prj_name/${pkg}
        done

        createrepo_c --update -q ${IMAGE_ROOTFS}/Packages.$prj_name/
    fi
}

# Update .buildstamp and copy rpm packages to IMAGE_ROOTFS
wrl_installer_copy_pkgs() {

    target_build="$1"
    target_image="$2"
    prj_name="$3"
    if [ -n "$4" ]; then
        installer_conf="$4"
    else
        installer_conf=""
    fi

    common_grep="-e '^ALL_MULTILIB_PACKAGE_ARCHS=.*' \
            -e '^MULTILIB_VARIANTS=.*' -e '^PACKAGE_ARCHS=.*'\
            -e '^PACKAGE_ARCH=.*' -e '^PACKAGE_INSTALL_ATTEMPTONLY=.*' \
            -e '^DISTRO=.*' -e '^DISTRO_NAME=.*' -e '^DISTRO_VERSION=.*' \
            "

    if [ -f "$installer_conf" ]; then
        eval "grep -e \"^PACKAGE_INSTALL=.*\" $common_grep $installer_conf \
            | sed -e 's/=/=\"/' -e 's/$/\"/' > ${BB_LOGFILE}.distro_vals"

        eval "cat $target_build/installersupport_$target_image | \
            grep -e '^WORKDIR=.*' >> ${BB_LOGFILE}.distro_vals"

        eval `cat ${BB_LOGFILE}.distro_vals`
        if [ $? -ne 0 ]; then
            bbfatal "Something is wrong in $installer_conf, please correct it"
        fi
        if [ -z "$PACKAGE_ARCHS" -o -z "$PACKAGE_INSTALL" ]; then
            bbfatal "PACKAGE_ARCHS or PACKAGE_INSTALL is null, please check $installer_conf"
        fi
    else
        eval "cat $target_build/installersupport_$target_image | \
            grep $common_grep -e '^PN=.*' -e '^SUMMARY=.*' -e '^WORKDIR=.*'\
            -e '^DESCRIPTION=.*' -e '^export PACKAGE_INSTALL=.*' > ${BB_LOGFILE}.distro_vals"

        eval `cat ${BB_LOGFILE}.distro_vals`
    fi

    export installer_default_arch="$PACKAGE_ARCH"
    # Reverse it for priority
    export installer_default_archs="`for arch in $PACKAGE_ARCHS; do echo $arch; done | tac | tr - _`"
    installer_target_archs="$installer_default_archs"
    if [ -n "$MULTILIB_VARIANTS" ]; then
        export MULTILIB_VARIANTS
        mlarchs_reversed="`for mlarch in $ALL_MULTILIB_PACKAGE_ARCHS; do echo $mlarch; \
            done | tac | tr - _`"
        for arch in $mlarchs_reversed; do
            if [ "$arch" != "noarch" -a "$arch" != "all" -a "$arch" != "any" ]; then
                installer_target_archs="$installer_target_archs $arch"
            fi
        done
    fi
    export installer_target_archs

    # Save the vars to .buildstamp when no installer_conf
    if [ ! -f "$installer_conf" ]; then
        cat >> ${IMAGE_ROOTFS}/.buildstamp.$prj_name <<_EOF
DISTRO=$DISTRO
DISTRO_NAME=$DISTRO_NAME
DISTRO_VERSION=$DISTRO_VERSION

[Rootfs]
LIST=$PN

[$PN]
SUMMARY=$SUMMARY
DESCRIPTION=$DESCRIPTION

PACKAGE_INSTALL=$PACKAGE_INSTALL
PACKAGE_INSTALL_ATTEMPTONLY=$PACKAGE_INSTALL_ATTEMPTONLY
ALL_MULTILIB_PACKAGE_ARCHS=$ALL_MULTILIB_PACKAGE_ARCHS
MULTILIB_VARIANTS=$MULTILIB_VARIANTS
PACKAGE_ARCHS=$PACKAGE_ARCHS
PACKAGE_ARCH=$PACKAGE_ARCH
IMAGE_LINGUAS=${IMAGE_LINGUAS}
_EOF
    fi

    if [ -d "$WORKDIR/oe-rootfs-repo/rpm" ]; then
        # Copy local repos while the image is not initramfs
        bpn=${BPN}
        if [ "${bpn##*initramfs}" = "${bpn%%initramfs*}" ]; then
            wrl_installer_copy_local_repos $WORKDIR/oe-rootfs-repo/rpm
        fi
        echo "$DISTRO::$prj_name::$DISTRO_NAME::$DISTRO_VERSION" >> ${IMAGE_ROOTFS}/.target_build_list
    fi
}

wrl_installer_get_count() {
    sum=0
    for i in $*; do
        sum=$(expr $sum + 1)
    done
    echo $sum
}

wrl_installer[vardepsexclude] = "DATETIME"
wrl_installer() {
    cat >${IMAGE_ROOTFS}/.discinfo <<_EOF
${DATETIME}
${DISTRO_NAME} ${DISTRO_VERSION}
${TARGET_ARCH}
_EOF

    : > ${IMAGE_ROOTFS}/.target_build_list
    counter=0
    targetimage_counter=0
    for target_build in ${INSTALLER_TARGET_BUILD}; do
        target_build="`readlink -f $target_build`"
        echo "Installer Target Build: $target_build"
        counter=$(expr $counter + 1)
        prj_name="`echo $target_build | sed -e 's#/ *$##g' -e 's#.*/##'`"
        prj_name="$prj_name-$counter"

	    # Generate .buildstamp
	    if [ -n "${WRL_INSTALLER_CONF}" ]; then
	        installer_conf="`echo ${WRL_INSTALLER_CONF} | awk '{print $'"$counter"'}'`"
	        wrl_installer_copy_buildstamp $prj_name $installer_conf
	    else
	        cat >${IMAGE_ROOTFS}/.buildstamp.$prj_name <<_EOF
[Main]
Product=${INSTPRODUCT}
Version=${INSTVER}
BugURL=${INSTBUGURL}
IsFinal=True
UUID=${DATETIME}.${TARGET_ARCH}
_EOF
	    fi

	    if [ -f "$target_build" ]; then
	        filename=$(basename "$target_build")
	        extension="${filename##*.}"
	        bpn=${BPN}
	        # Do not copy image for initramfs
	        if [ "${bpn##*initramfs}" != "${bpn%%initramfs*}" ]; then
	            continue
	        elif [ "x$extension" = "xext2" -o "x$extension" = "xext3" -o "x$extension" = "xext4" ]; then
	            echo "Image based target install selected."
	            mkdir -p "${IMAGE_ROOTFS}/LiveOS.$prj_name"
	            wrl_installer_hardlinktree "$target_build" "${IMAGE_ROOTFS}/LiveOS.$prj_name/rootfs.img"
	            echo "::$prj_name::" >> ${IMAGE_ROOTFS}/.target_build_list
	        else
	            bberror "Unsupported image: $target_build."
	            bberror "The image must be ext2, ext3 or ext4"
	            exit 1
	        fi
	    elif [ -d "$target_build" ]; then
	        targetimage_counter=$(expr $targetimage_counter + 1)
	        target_image="`echo ${INSTALLER_TARGET_IMAGE} | awk '{print $'"$targetimage_counter"'}'`"
	        echo "Target Image: $target_image"
	        wrl_installer_copy_pkgs $target_build $target_image $prj_name $installer_conf
	    else
	        bberror "Invalid configuration of INSTALLER_TARGET_BUILD: $target_build."
	        bberror "It must either point to an image (ext2, ext3 or ext4) or to the root of another build directory"
	        exit 1
	    fi

	    ks_cfg="${INSTALLER_CONFDIR}/ks.cfg.$prj_name"
	    if [ -n "${KICKSTART_FILE}" ]; then
	        ks_file="`echo ${KICKSTART_FILE} | awk '{print $'"$counter"'}'`"
	        bbnote "Copying kickstart file $ks_file to $ks_cfg ..."
	        mkdir -p ${INSTALLER_CONFDIR}
	        cp $ks_file $ks_cfg
	    fi
	    if [ -n "${KICKSTART_FILE_EXTRA}" ]; then
	        for ks_file in ${KICKSTART_FILE_EXTRA}; do
	            if [ -f $ks_file ]; then
	                cp $ks_file ${INSTALLER_CONFDIR}
	            else
	                bbwarn "The kickstart file $ks_file in KICKSTART_FILE_EXTRA doesn't exist!"
	            fi
	        done
	    fi
    done

    # Setup the symlink if only one target build dir.
    if [ "$counter" = "1" ]; then
        prj_name="`awk -F:: '{print $2}' ${IMAGE_ROOTFS}/.target_build_list`"
        entries=".buildstamp LiveOS Packages installer-config/ks.cfg"
        for i in $entries; do
            if [ -e ${IMAGE_ROOTFS}/$i.$prj_name ]; then
                ln -sf `basename $i.$prj_name` ${IMAGE_ROOTFS}/$i
            fi
        done
    fi
}

python __anonymous() {
    if "selinux" in d.getVar("DISTRO_FEATURES", True).split():
        raise bb.parse.SkipPackage("Unable to build the installer when selinux is enabled.")

    if bb.data.inherits_class('image', d):
        if d.getVar("DISTRO", True) != "anaconda":
            raise bb.parse.SkipPackage("Set DISTRO = 'anaconda' in local.conf")

        target_builds = d.getVar('INSTALLER_TARGET_BUILD', True)
        if not target_builds:
            errmsg = "No INSTALLER_TARGET_BUILD is found,\n"
            errmsg += "set INSTALLER_TARGET_BUILD = '<target-build-topdir>' and\n"
            errmsg += "INSTALLER_TARGET_IMAGE = '<target-image-pn>' to do RPMs\n"
            errmsg += "install, or\n"
            errmsg += "set INSTALLER_TARGET_BUILD = '<target-build-image>' to do\n"
            errmsg += "image copy install"
            raise bb.parse.SkipPackage(errmsg)

        count = 0
        for target_build in target_builds.split():
            if not os.path.exists(target_build):
                raise bb.parse.SkipPackage("The %s of INSTALLER_TARGET_BUILD does not exist" % target_build)

            if os.path.isdir(target_build):
                count += 1

        # While do package management install
        if count > 0:
            target_images = d.getVar('INSTALLER_TARGET_IMAGE', True)
            if not target_images:
                errmsg = "The INSTALLER_TARGET_BUILD is a dir, but not found INSTALLER_TARGET_IMAGE,\n"
                errmsg += "set INSTALLER_TARGET_IMAGE = '<target-image-pn>' to do RPMs install"
                raise bb.parse.SkipPackage(errmsg)

            elif count != len(target_images.split()):
                errmsg = "The INSTALLER_TARGET_BUILD has %s build dirs: %s\n" % (count, target_builds)
                errmsg += "But INSTALLER_TARGET_IMAGE has %s build images: %s\n" % (len(target_images.split()), target_images)
                raise bb.parse.SkipPackage(errmsg)

        # The count of INSTALLER_TARGET_BUILD and WRL_INSTALLER_CONF must match when set.
        wrlinstaller_confs = d.getVar('WRL_INSTALLER_CONF', True)
        if wrlinstaller_confs:
            if len(wrlinstaller_confs.split()) != len(target_builds.split()):
                raise bb.parse.SkipPackage("The count of INSTALLER_TARGET_BUILD and WRL_INSTALLER_CONF not match!")
            for wrlinstaller_conf in wrlinstaller_confs.split():
                if not os.path.exists(wrlinstaller_conf):
                    raise bb.parse.SkipPackage("The installer conf %s in WRL_INSTALLER_CONF doesn't exist!" % wrlinstaller_conf)

        # The count of INSTALLER_TARGET_BUILD and KICKSTART_FILE must match when set.
        kickstart_files = d.getVar('KICKSTART_FILE', True)
        if kickstart_files:
            if len(kickstart_files.split()) != len(target_builds.split()):
                raise bb.parse.SkipPackage("The count of INSTALLER_TARGET_BUILD and KICKSTART_FILE not match!")
            for kickstart_file in kickstart_files.split():
                if not os.path.exists(kickstart_file):
                    raise bb.parse.SkipPackage("The kickstart file %s in KICKSTART_FILE doesn't exist!" % kickstart_file)

}

python build_syslinux_cfg () {
    import copy
    import sys

    workdir = d.getVar('WORKDIR')
    if not workdir:
        bb.error("WORKDIR not defined, unable to package")
        return

    cfile = d.getVar('SYSLINUX_CFG')
    if not cfile:
        bb.fatal('Unable to read SYSLINUX_CFG')
}
