#!/bin/sh -f
 
po_domain="alterator-livecd"
alterator_api_version=1
source_file="${source_dir:-/image/live}"
target_dir="${target_dir:-/mnt/destination}"
preinstall_hooks_dir=/usr/lib/alterator/hooks/livecd-preinstall.d
postinstall_hooks_dir=/usr/lib/alterator/hooks/livecd-postinstall.d
install_pid=

export target_dir

. alterator-sh-functions

do_notify()
{
    alterator-mailbox-send "$1 \"$(write_string "$2")\""
    echo "message:$1 $2" >&2
    sleep 1
}

do_notify_error()
{
    do_notify error "$1"
}

do_notify_status()
{
    do_notify status "$1"
}

do_notify_stage()
{
    do_notify stage "$1"
}

##
# Calculate unpacked sqaushfs size
# 
sqfs_size() {
        local total=0 file_size=0

        local img="$1" && shift

        [ -f "$img" ] || return 1


        unsquashfs -ll "$img" 2>/dev/null | sed -e '1,3d' -e 's/[[:space:]]\+/ /g' | cut -f 3 -d ' ' | sed -e '/,/d' |
        {
            local total=0 file_size=0

            while read file_size; do
                ((total += file_size))
            done

            echo $total
        }

        return 0
}

##
# Return free space in bytes on mounted file system
#
free_space() {
        local target="$1" && shift

        [ -e "$target" ] || return 1

        df --block-size=1 "$target" | sed -e '1d' -e 's/[[:space:]]\+/ /g' | cut -d ' ' -f 4

        return 0
}

##
# unpack squashfs image
#

do_install()
{
    local img="$1";shift
    local dst="$1";shift
    local percent1=

    if ! [ -r "$img" ]; then
        do_notify_error "Can't read squashfs image $img"
        return 1
    fi

    if ! mkdir -p -- "$dst";then
        do_notify_error "Can't write to $dst directory"
        return 1
    fi

    do_notify_stage preinstall
    run-parts "$preinstall_hooks_dir"
    
    # calculate inodes per one percent
    percent1="$(unsquashfs -n -s "$img"  | grep inodes | sed -e 's/[^[:digit:]]\+//')"
    percent1="$((percent1/99))"

    # calculate size necessary for unpacked squashfs image
    local unpacked=$(sqfs_size "$img")

    if [ -z "$unpacked" ]; then
        do_notify_error "Can't calculate unpacked squashfs size"
        return 1
    fi
   
    local free=$(free_space "$target_dir")

    if [ $unpacked -gt $free ]; then
        do_notify_error "No free space to unpack squashfs image"
        return 1
    fi

    do_notify_stage install

    unsquashfs -force -no-progress -info -dest "$dst" "$img" 2>/dev/null |
    {
        local i=0
        local progress=0

        while read ignore; do
            ((i += 1))
            if [ $i -gt $percent1 ]; then
                do_notify_status "$((progress++))"
                i=0
             fi
        done
    }

    do_notify_stage postinstall

    for i in proc dev sys; do
        mkdir -p -- "$target_dir/$i"
        mountpoint -q "$target_dir/$i" || mount --bind /$i "$target_dir/$i"
    done

    run-parts "$postinstall_hooks_dir"

    do_notify_stage done

    return 0
}

on_message()
{
        case "$in_action" in
                write)
                    if [ -n "$install_pid" ] && kill -0 "$install_pid" ;then
                        write_error "Process already running"
                        return
                    fi
                    do_install "$source_file" "$target_dir"&
                    install_pid=$!
                    ;;
        esac
}

message_loop
