# -*- mode: shell-script -*-


make_build_script() {
    local users_def="$1" cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" "$(declare -f "$FUNCNAME")" | md5_compat)"
    if [ -e "$cache_file" ]; then
        #debug "$FUNCNAME: STATIC cache hit"
        cat "$cache_file" &&
        touch "$cache_file" || return 1
        return 0
    fi
    ## remaining arguments are the group_label:gid list that should be
    ## avoided for creation (because already existent ?)
    shift

    local code fixed_groups_code groups_code \
          created_groups first_group gids

    if [ -z "$users_def" ]; then
        return 0
    fi
    e "set -eux"$'\n'
    code=""
    fixed_groups_code=""
    groups_code=""
    gids=()
    declare -A created_groups
    for group in "$@"; do
        if [[ "$group" != *":"* ]]; then
            err "Invalid group specification given from script"
            return 1
        fi
        gid=${group##*:}
        gids+=("$gid")
        group_label=${group%%:*}
        created_groups[$group_label]="$gid"
    done

    while read-0 user user_def; do

        code+="mkdir -p \"/home/$user\""$'\n'

        ##
        ## Group management
        ##

        first_group=
        first=1
        while read-0 group; do
            gid="unspecified"
            if [[ "$group" == *":"* ]]; then
                gid=${group##*:}
                if ! [[ "$gid" =~ ^[0-9]+$ ]]; then
                    err "gid part (after ':') should be numerical not '$gid'."
                    return 1
                fi
                group_label=${group%%:*}
            else
                group_label="$group"
            fi
            if [ "${created_groups[$group_label]}" ]; then  ## already met this group
                ## double-check we did not give conflicting gid information
                if [[ "${created_groups[$group_label]}" != "$gid" ]]; then
                    err "Conflicting setup: using existing group '$group_label' for user '$user'" \
                        "with different GIDs specification" \
                        "(previous was ${created_groups[$group_label]}, current one is $gid)."
                    return 1
                fi
            else
                if [[ "$gid" != unspecified ]]; then
                    ## check not already used
                    if [[ " ${gids[*]} " == *" $gid "* ]]; then
                        err "gid $gid is alreay used and is not available."
                        return 1
                    fi
                    fixed_groups_code+="addgroup -g \"$gid\" \"$group_label\""$'\n'
                else
                    groups_code+="addgroup \"$group\""$'\n'
                fi
                created_groups[$group_label]="$gid"
            fi
            echo "First: $first" >&2
            echo "First: $group_label" >&2
            if [ "$first" ]; then
                echo "FG1: $first_group" >&2
                first_group="$group_label"
                first=
            else
                remaining_groups+=("$group_label")
            fi
        done < <(echo "$user_def" | shyaml get-values-0 groups 2>/dev/null)

        ##
        ## User create commands
        ##

        uid=$(echo "$user_def" | shyaml get-value uid 2>/dev/null)

        useradd_options=(
            "-D"                ## don't assign a password
            "-s" "/bin/false"   ## default shell
        )
        if [ "$uid" ]; then
            useradd_options+=("-u" "$uid")    ## force uid
        fi
        if [ "$first_group" ]; then
            useradd_options+=("-G" "$first_group")  ## force main group
        fi

        code+="adduser ${useradd_options[*]} \"$user\""$'\n'
        if [ "$allow_writeable_chroot" ]; then
            code+="chown $user \"/home/$user\""$'\n'  ## sanitize
        else
            code+="chown root:root \"/home/$user\""$'\n'  ## sanitize
        fi
        code+="chmod 755 \"/home/$user\""$'\n'        ## sanitize
        password=$(echo "$user_def" | shyaml get-value password 2>/dev/null) ||
            password=$(gen_password 14)
        code+="echo '$user:$password' | chpasswd"$'\n'
        for group in "${remaining_groups[@]}"; do
            code+="adduser \"$user\" \"$group\""$'\n'
        done

        ##
        ## Key managements
        ##

        while read-0 key; do
            keys+="$key"$'\n'
        done < <(echo "$user_def" | shyaml get-values-0 -q keys)
        if [ "$keys" ]; then
            code+="mkdir -p \"/home/$user/.ssh\""$'\n'
            code+="cat <<EOF > /home/$user/.ssh/authorized_keys"$'\n'
            code+="$keys"
            code+="EOF"$'\n'
            # code+="chown $user /home/$user/.ssh/authorized_keys"$'\n'
            code+="chmod 644 /home/$user/.ssh/authorized_keys"$'\n'
            code+="chmod 755 /home/$user/.ssh"$'\n'

        fi

    done < <(echo "$users_def" | shyaml key-values-0)
    {
        echo -n "$fixed_groups_code"
        echo -n "$groups_code"
        echo -n "$code"
    } | tee "$cache_file"
}