#!/usr/bin/env bash
# Desc: Insert string into provided string

yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
must() { "$@" || die "cannot $*"; }
insertStr() {
    # Desc: Inserts a string into another string at a specified position.
    # Input: arg1: str   str_rec  String to receive insertion
    #        arg2: int   pos      Insertion position (0 = append to front)
    #        arg3: str   str_ins  String to be inserted
    # Output: stdout:    Combined string
    # Version: 0.0.2
    # Depends: BK-2020-03: yell(), die(), must()
    # Ref/Attrib: * BK-2020-03: https://gitlab.com/baltakatei/baltakatei-exdev/
    #             * Cooper, Mendel. “Advanced Bash-Scripting Guide: Manipulating Strings”. tldp.org https://tldp.org/LDP/abs/html/string-manipulation.html

    local str_rec pos str_ins re len_str_rec;
    local pfx_pos_start pfx_len pfx;
    local sfx_pos_start sfx_len sfx;

    # Check args
    if [[ $# -ne 3 ]]; then
        yell "ERROR:Invalid argument count:$#";
        return 1; fi;
    re='^[0-9]+$';
    if [[ ! "$2" =~ $re ]]; then
        yell "ERROR:Not an int:$2";
        return 1; fi;
    str_rec="$1";
    pos="$2";
    str_ins="$3";

    # Calculate string stats
    len_str_rec="${#str_rec}";

    # Form prefix
    pfx_pos_start="0";
    pfx_len="$pos";
    pfx="${str_rec:$pfx_pos_start:$pfx_len}";

    # Form suffix
    sfx_pos_start="$(( pos ))";
    sfx_len="$(( len_str_rec - pos ))";
    sfx="${str_rec:$sfx_pos_start:$sfx_len}";

    # Print output to stdout
    printf "%s%s%s\n" "$pfx" "$str_ins" "$sfx";
}; # Insert string provided at indicated position via stdout


# Tests
printf "\"%s\" should read \"foobarbaz\"\n" "$(insertStr "foobaz" 3 "bar";)";

insertStr "foobaz" 0 "bar";
insertStr "foobaz" 1 "bar";
insertStr "foobaz" 2 "bar";
insertStr "foobaz" 3 "bar";
insertStr "foobaz" 4 "bar";
insertStr "foobaz" 5 "bar";
insertStr "foobaz" 6 "bar";
insertStr "foobaz" 7 "bar";
insertStr "foobaz" 999 "bar";