#!/usr/bin/env bash

set -x
cd "$(dirname $(readlink -f ${0}))"||exit 1

. ../.config

INITRAMFS="/tmp/MlbInitRd"
trap "rm -rf ${INITRAMFS}&&exit 1" 2 3 6 15

# copy file to initramfs tree, including
# all library dependencies (as shown by ldd)
# $1 = file to copy (full path)
copy_including_deps()
{
   # if source doesn't exist or target exists, do nothing
   if [ ! -e "$1" -o -e "$INITRAMFS"/"$1" ]; then
      return 1
   fi

   cp -R --parents "$1" "$INITRAMFS"
   if [ -L "$1" ]; then
      DIR="$(dirname "$1")"
      LNK="$(readlink "$1")"
      copy_including_deps "$(cd "$DIR"; realpath -s "$LNK")"
   fi

   ldd "$1" 2>/dev/null | sed -r "s/.*=>|[(].*//g" | sed -r "s/^\\s+|\\s+\$//" \
     | while read LIB; do
        copy_including_deps "$LIB"
     done

   for MOD in $(find "$1" -type f -name "*.ko"); do
      for DEP in $(cat /$LMK/modules.dep | fgrep /$(basename $MOD):); do
         copy_including_deps "/$LMK/$DEP"
      done
   done

   shift
   if [ "$1" != "" ]; then
       copy_including_deps "$@"
   fi
}

rm -Rf $INITRAMFS
mkdir -p $INITRAMFS/{bin,dev,etc,lib,lib64,mnt,proc,root,run,sys,tmp,usr,var/log}
mkdir -p $INITRAMFS/usr/{sbin,bin}
ln -s bin $INITRAMFS/sbin

# If bb is not found use all static prebuilt
copy_including_deps /bin/busybox || { cp static/busybox $INITRAMFS/bin;static="true"; }
for i in $($INITRAMFS/bin/busybox --list|egrep -v "tar|init"); do [ ! -e $INITRAMFS/bin/$i ]&&ln -sf busybox $INITRAMFS/bin/$i; done

mknod $INITRAMFS/dev/console c 5 1
mknod $INITRAMFS/dev/null c 1 3
mknod $INITRAMFS/dev/ram0 b 1 0
mknod $INITRAMFS/dev/tty1 c 4 1
mknod $INITRAMFS/dev/tty2 c 4 2
mknod $INITRAMFS/dev/tty3 c 4 3
mknod $INITRAMFS/dev/tty4 c 4 4

copy_including_deps /$LMK/kernel/fs
for LINE in $(find /$LMK/kernel/ | grep crc32c); do
   copy_including_deps $LINE
done
copy_including_deps /$LMK/kernel/drivers/staging/zsmalloc # needed by zram
copy_including_deps /$LMK/kernel/drivers/block/zram
copy_including_deps /$LMK/kernel/drivers/block/loop.*
# usb drivers
copy_including_deps /$LMK/kernel/drivers/usb/storage/usb-storage.*
copy_including_deps /$LMK/kernel/drivers/usb/host
copy_including_deps /$LMK/kernel/drivers/usb/common
copy_including_deps /$LMK/kernel/drivers/usb/core
copy_including_deps /$LMK/kernel/drivers/hid/usbhid
copy_including_deps /$LMK/kernel/drivers/hid/hid.*
copy_including_deps /$LMK/kernel/drivers/hid/uhid.*
copy_including_deps /$LMK/kernel/drivers/hid/hid-generic.*
# disk and cdrom drivers
copy_including_deps /$LMK/kernel/drivers/cdrom
copy_including_deps /$LMK/kernel/drivers/scsi/sr_mod.*
copy_including_deps /$LMK/kernel/drivers/scsi/sd_mod.*
copy_including_deps /$LMK/kernel/drivers/scsi/scsi_mod.*
copy_including_deps /$LMK/kernel/drivers/scsi/sg.*
copy_including_deps /$LMK/kernel/drivers/ata
copy_including_deps /$LMK/kernel/drivers/nvme
copy_including_deps /$LMK/kernel/drivers/mmc

# copy all custom-built modules
copy_including_deps /$LMK/updates
copy_including_deps /$LMK/modules.*

cp static/mount.dynfilefs $INITRAMFS/bin
cp static/fsck $INITRAMFS/bin
[[ ${static} ]]&&cp static/bash $INITRAMFS/bin||copy_including_deps /bin/bash
[[ ${static} ]]&&cp static/tar $INITRAMFS/bin||copy_including_deps /bin/tar||copy_including_deps /usr/bin/tar
[[ ${static} ]]&&cp static/e2fsck $INITRAMFS/bin||copy_including_deps /sbin/e2fsck
[[ ${static} ]]&&cp static/fsck.fat $INITRAMFS/bin||copy_including_deps /sbin/fsck.fat
[[ ${static} ]]&&cp static/f2fs $INITRAMFS/bin||copy_including_deps /sbin/fsck.f2fs
[[ ${static} ]]&&cp static/mdadm $INITRAMFS/bin||copy_including_deps /sbin/mdadm
[[ ${static} ]]&&cp static/mount.ntfs-3g $INITRAMFS/bin||copy_including_deps /sbin/mount.ntfs-3g
#[[ ${static} ]]&&cp static/blkid $INITRAMFS/bin||copy_including_deps /sbin/blkid
#copy_including_deps /usr/bin/eject || cp static/eject $INITRAMFS/bin

# trim modules.order file. Perhaps we could remove it entirely
MODULEORDER="$(cd "$INITRAMFS/$LMK/"; find -name "*.ko" | sed -r "s:^./::g" | tr "\n" "|" | sed -r "s:[.]:.:g")"
cat $INITRAMFS/$LMK/modules.order | sed -r "s/.ko.gz\$/.ko/" | grep -E "$MODULEORDER"/foo/bar > $INITRAMFS/$LMK/_
mv $INITRAMFS/$LMK/_ $INITRAMFS/$LMK/modules.order

depmod -b $INITRAMFS $(ls $INITRAMFS/lib/modules | sort)

echo "root::0:0::/root:/bin/sh" >$INITRAMFS/etc/passwd
touch $INITRAMFS/etc/{m,fs}tab

cp shutdown $INITRAMFS
cp functions $INITRAMFS/lib
cp init $INITRAMFS
ln -s ../init $INITRAMFS/bin/init
cp ../.config $INITRAMFS/lib
chmod a+x -R $INITRAMFS

cd $INITRAMFS
find | cpio -R root:root -o -H newc 2>/dev/null | gzip -cf9 >$INITRAMFS.img
echo $INITRAMFS.img

cd ..
rm -rf $INITRAMFS
[[ ${static} ]]&&exit 2||exit 0
