#!/bin/bash
# MKit - simple install helper
# See LICENSE file for copyright and license details.

mkit_import ini

__deploy_item() {
    #
    # Deploy item and make it look like wanted
    #
    # usage: __deploy_item src dst [mode]
    #
    # Both src and dst must be names of actual items[1],
    # whereas dst must not exist.  On update, dst is
    # usually to be replaced but that is uninstall's
    # job!
    #
    #  [1] Ie. src=foo and dst=/foo/bar does *always*
    #      mean that foo will become 'bar'.  This is
    #      different than traditional `cp` behavior,
    #      when this depends if 'bar' already exists
    #      as a directory.
    #
    # If mode is omitted or empty, MKIT_DEFAULT_MODE is
    # used instead.
    #
    # Directories are copied recursively, and mode is
    # applied only to files.
    #
    local src=$1                            # source path
    local dst=$2                            # destination path
    local mode=${3:-$MKIT_DEFAULT_MODE}     # mode
    local item                              # each in directory
    if test -d "$src"; then
        find "$src" -type f \
          | while read -r item; do
                [[ $item =~ .skel$ ]] \
                 && grep -q "${item%.skel}" "$MKIT_LOCAL/built.lst" \
                 && continue
                __deploy_item "$item" "$dst${item#$src}" "$mode"
            done
    else
        test "$mode" == "SRC" && mode=$(stat -c "%a" "$src")
        __maybe install -DTvm "$mode" "$src" "$dst"
    fi
}

__get_dst() {
    #
    # Find out target path for src file $2 of group $1
    #
    local grp=$1        # deploy group
    local src=$2        # each source
    local dst=$3        # alternative destination name
    test -n "$dst" || dst=${src##*/}
    echo "$(__get_root "$grp")/$dst"
}

__get_root() {
    #
    # Find out target root for group $1
    #
    local grp=$1        # deploy group
    local root          # root for this group
    local destdir       # value of DESTDIR
    root=$(ini 1value "roots:$grp")
    destdir=$(ini 1value ENV:DESTDIR)
    destdir=${destdir%/}
    case $destdir:$root in
        *:)     die "missing in config.ini: roots:$grp" ;;
        :*)     echo "$root" ;;
        *:*)    echo "$destdir/$root" ;;
    esac
}

__maybe() {
    #
    # Call the deploy command $1 $@ unless in dry mode
    #
    debug "$@"
    local cmd="$1"; shift
    $MKIT_DRY && return
    case "$cmd" in
        cp|rm|rmdir|chmod|mkdir) $cmd "$@" ;;
        install)                 command -p install "$@" ;;
        *)                       die "bad command called";;
    esac
}

install() {
    #
    # Install product
    #
    local group     # each deploy group
    local mode      # mode (group-specific)
    local src       # each source path
    local dst       # each (final absolute) destination path
    ini lskeys "files" \
      | sort \
      | uniq \
      | while read -r group; do
            mode=$(ini 1value "modes:$group")
            ini values "files:$group" \
              | while read -r src dst; do
                    dst=$(__get_dst "$group" "$src" "$dst")
                    __deploy_item "$src" "$dst" "$mode"
                done
        done
    test -f "$MKIT_LOCAL/autoclean" && clean
    true
}

uninstall() {
    #
    # Uninstall product
    #
    local group     # each deploy group
    local src       # each source path
    local dst       # each (final absolute) destination path
    ini lskeys "files" \
      | sort \
      | uniq \
      | while read -r group; do
            ini values "files:$group" \
              | while read -r src dst; do
                    dst=$(__get_dst "$group" "$src" "$dst")
                    __maybe rm -vrf "$dst"
                done
        done
}