#!/bin/sh

command -v getarg > /dev/null || . /lib/dracut-lib.sh

generator_add_symlink() {
    local generator_dir="$1"
    local target="$2"
    local unit="$3"

    ! [ -L "$generator_dir/$target/$unit" ] || return 0
    [ -d "$generator_dir/$target" ] || mkdir -p "$generator_dir/$target"
    ln -s "../$unit" "$generator_dir/$target/$unit"
}

transfer_generate() {
    local generator_dir="$1"
    local url="$2"
    local type="$3"
    local before image_name image_root import_service json local_path_escaped loop_service mount_options mount_path

    if [ "$type" = raw ]; then
        image_name=rootdisk
        image_root=/var/lib/machines
        local_path_escaped="var-lib-machines-${image_name}.raw"
        mount_path="/dev/disk/by-loop-ref/$image_name.raw"
        mount_options=ro

        loop_service="systemd-loop@${local_path_escaped}.service"
        before=" $loop_service"
        generator_add_symlink "$generator_dir" imports.target.wants "$loop_service"
    else
        image_name=root
        image_root=/run/machines
        local_path_escaped="run-machines-${image_name}"
        mount_path="/run/machines/$image_name"
        mount_options=rw,bind
    fi

    import_service="systemd-import@${local_path_escaped}.service"
    json="{\"remote\":\"${url}\",\"local\":\"${image_name}\",\"type\":\"${type}\",\"class\":\"machine\",\"verify\":\"no\",\"imageRoot\":\"${image_root}\"}"
    cat > "$generator_dir/${import_service}" << EOF
# Automatically generated by ${0##*/}

[Unit]
Description=Download of ${url}
Documentation=man:systemd-import-generator(8)
SourcePath=/proc/cmdline
Requires=systemd-importd.socket
After=imports-pre.target systemd-importd.socket network-online.target
Conflicts=shutdown.target
Before=imports.target shutdown.target${before}
DefaultDependencies=no
Wants=network-online.target

[Service]
Type=oneshot
NotifyAccess=main
ExecStart=:varlinkctl call -q --more --timeout=infinity /run/systemd/io.systemd.Import io.systemd.Import.Pull '${json}'
EOF
    generator_add_symlink "$generator_dir" imports.target.wants "$import_service"

    cat > "$generator_dir/sysroot.mount" << EOF
# Automatically generated by ${0##*/}

[Unit]
SourcePath=/proc/cmdline
Before=initrd-root-fs.target
After=imports.target

[Mount]
What=$mount_path
Where=/sysroot
Options=$mount_options
EOF
    generator_add_symlink "$generator_dir" initrd-root-fs.target.requires sysroot.mount
    generator_add_symlink "$generator_dir" initrd-usr-fs.target.requires sysroot.mount
}

parse_root() {
    local generator_dir="$1"
    local root="$2"
    local type url

    case "$root" in
        tar:http*)
            url="${root#*:}"
            type=tar
            ;;
        squash:http*)
            url="${root#*:}"
            type=raw
            ;;
        http*.tar.?? | http*.tar.??? | http*.t?z)
            url="$root"
            type=tar
            ;;
        http*squash | http*squashfs)
            url="$root"
            type=raw
            ;;
        *)
            return 0
            ;;
    esac

    transfer_generate "$generator_dir" "$url" "$type"
}

parse_root "$1" "$(getarg root=)"
