# shellcheck shell=dash

___x_cmd_str_ml(){
    [ $# -gt 0 ] || {
        # TODO: show help
        return 64
    }

    local op=$1; shift
    case "$op" in
        wrap|wrap_|pwrap|pwrap_|trim|trim_)
            ___x_cmd_str_ml_"$op" "$@"
            ;;
        *)
            x:debug "unknown operation: $op"
            return 64
            ;;
    esac
}

___x_cmd_str_ml_wrap(){
    local x_=
    ___x_cmd_str_ml_wrap_ "$@"
    printf "%s" "$x_"
}

___x_cmd_str_ml_wrap_(){
    local data="$1"
    local begin="$2"
    local end="$3"

    # ref: https://stackoverflow.com/questions/7314044/use-bash-to-read-line-by-line-and-keep-space
    local IFS="$___X_CMD_UNSEENCHAR_NEWLINE"
    local line
    while read -r line; do
        ___x_cmd_str_ml___append "${begin}${line}${end}"
    done <<A
$data
A
}

___x_cmd_str_ml_pwrap(){
    local x_=
    ___x_cmd_str_ml_pwrap_ "$@"
    printf "%s" "$x_"
}

___x_cmd_str_ml_pwrap_(){
    local begin="$1"
    local end="$2"

    local IFS="$___X_CMD_UNSEENCHAR_NEWLINE"
    local line
    while read -r line; do
        ___x_cmd_str_ml___append "${begin}${line}${end}"
    done
}

___x_cmd_str_ml_trim(){
    local x_=
    ___x_cmd_str_ml_trim_ "$@"
    printf "%s" "$x_"
}

___x_cmd_str_ml_trim_(){
    local data="$1"
    local begin="$2"
    local end="$3"

    local line
    while read -r line; do
        line="${line#"${line%%[![:space:]]*}"}"
        ___x_cmd_str_ml___append "${line%"${line##*[![:space:]]}"}"
    done <<A
$data
A
}

___x_cmd_str_ml___append(){
    if [ -z "$x_" ]; then
        x_="$1"
    else
        x_="${x_}${___X_CMD_UNSEENCHAR_NEWLINE}${1}"
    fi
}

