#!/bin/sh

VERSION="1.2"

print_version()
{
    echo "${VERSION}"
    exit 0
}

print_help()
{
    echo "\
Usage:
subcom [-a | -w | -s] [-p PATH] [-d | -n] [--] SCRIPT ARGUMENTS
subcom --help | --version

Tool to manage subcommands of your executable.
"
    exit 0
}

error()
{
    echo "Error:" 1>&2
    echo "$@" 1>&2
    exit 1
}

error_code()
{
    echo "Error:" 1>&2
    echo "$@" 1>&2
}

handle_result()
{
    subcom_exec="$1"
    shift || true
    arg_list="$1"
    shift || true

    if test -n "${ALL_ARGS}" ; then
        printf "%s\n%s\n" "${subcom_exec}" "${@}"
        exit 0
    fi
    if test -n "${ONLY_OTHER_ARGS}" ; then
        printf "%s\n" "${@}"
        exit 0
    fi
    if test -n "${LISTED_ARGS}" ; then
        printf "%s\n" "${arg_list}"
        exit 0
    fi

    printf "%s\n" "${subcom_exec}"
    exit 0
}

local_which()
{
    arg="$1"

    if test -x "${arg}" ; then
        printf "%s\n" "${arg}"
        return 0
    fi

    IFS=:
    for dir in ${PATH} ; do
        if test -x "${dir}/${arg}" ; then
            printf "%s\n" "${dir}/${arg}"
            return 0
        fi
    done
    return 1
}

error_NOEXEC=2
error_NOPERMEXEC=3
error_NOPATH=4

ALL_ARGS=
ONLY_OTHER_ARGS=
LISTED_ARGS=
COMMAND_PATH=
ONLY_DASHES=
ONLY_NESTED=

# -------------------------- execution -----------------------------------------


in_opt_cycle=1

while test -n "$1" ; do
    arg="$1"
    shift

    if test -n "${in_opt_cycle}" ; then
        checked_arg="${arg#-}" || true
        if test "$checked_arg" != "${arg}" ; then
            case ${checked_arg} in
                a)
                    ALL_ARGS=1
                    ONLY_OTHER_ARGS=
                    LISTED_ARGS=
                ;;
                w)
                    ONLY_OTHER_ARGS=1
                    ALL_ARGS=
                    LISTED_ARGS=
                ;;
                s)
                    LISTED_ARGS=1
                    ALL_ARGS=
                    ONLY_OTHER_ARGS=
                ;;
                p)
                    COMMAND_PATH="$1"
                    shift || error "No argument for option -p"
                ;;
                d)
                    ONLY_DASHES=1
                    ONLY_NESTED=
                ;;
                n)
                    ONLY_NESTED=1
                    ONLY_DASHES=
                ;;
                -version)
                    print_version
                ;;
                -help)
                    print_help
                ;;
                -)
                    in_opt_cycle=
                ;;
                *)
                    error "Unknown option ${arg}"
                ;;
            esac

            continue
        else
            break
        fi
    fi

done

# detect main executable
if test -z "${arg}" ; then
    error_code "No executable was given in command string"
    exit ${error_NOEXEC}
fi
EXEC="$( local_which ${arg} )"
if test ! -x "${EXEC}" ; then
    error_code "Given main file is not executable"
    exit ${error_NOPERMEXEC}
fi

subcom_exec="${EXEC}"
arg_list=

if test -n "${COMMAND_PATH}" ; then
    if test ! -d "${COMMAND_PATH}" ; then
        error_code "Explicitly given path is not available"
        exit ${error_NOPATH}
    fi
    COMMAND_PATH="$( cd ${COMMAND_PATH} ; pwd -P )"
    subcom_name="${EXEC##*/}"
    subcom_exec="${COMMAND_PATH}/${subcom_name}"
fi

# detect subcommands

if test -z "${ONLY_NESTED}" ; then

    # scheme /usr/bin/foo-bar-one-two
    # (or ${COMMAND_PATH}/foo-bar-one-two, it will be checked at the same time)
    dash_found=
    while test -n "$1" ; do
        val="$1"
        exec_pretend="${subcom_exec}-${val}"
        if test -f "${exec_pretend}" -a -x "${exec_pretend}" ; then
            subcom_exec="${exec_pretend}"
            arg_list="${arg_list} ${val}"
            dash_found=1
            shift
        else
            break
        fi
    done

    if test -n "${dash_found}" ; then
        handle_result "${subcom_exec}" "${arg_list}" "${@}"
    fi

    # nothing found in /usr/bin
    # let's try in /usr/lib/foo/foo-bar-one-two
    dash_found=
    subcom_name="${EXEC##*/}"
    # emulate ${EXEC}/../../
    tmp_dir="${EXEC%/*}"
    tmp_dir="${tmp_dir%/*}"
    # /usr/lib/foo/
    subcom_exec="${tmp_dir}/lib/${subcom_name}/${subcom_name}"

    while test -n "$1" ; do
        val="$1"
        exec_pretend="${subcom_exec}-${val}"
        if test -f "${exec_pretend}" -a -x "${exec_pretend}" ; then
            subcom_exec="${exec_pretend}"
            arg_list="${arg_list} ${val}"
            dash_found=1
            shift
        else
            break
        fi
    done

    if test -n "${dash_found}" ; then
        handle_result "${subcom_exec}" "${arg_list}" "${@}"
    fi

fi

# nothing found with schemes:
# /usr/bin/foo-bar-one-two
# /usr/lib/foo/foo-bar-one-two
# let's try /usr/libexec/foo/bar/one/two

if test -z "${ONLY_DASHES}" ; then

    subcom_name="${EXEC##*/}"
    if test -n "${COMMAND_PATH}" ; then
        curdir="${COMMAND_PATH}/${subcom_name}"
    else
        subcom_prefix="libexec/${subcom_name}"
        # emulate ${EXEC}/../../
        tmp_dir="${EXEC%/*}"
        tmp_dir="${tmp_dir%/*}"
        # /usr/libexec/foo/
        curdir="${tmp_dir}/${subcom_prefix}"
    fi

    subcom_exec=
    previous_dir=
    prev_val=

    while test -n "$1" ; do
        val="$1"
        if test -f "${curdir}/${val}" -a -x "${curdir}/${val}" ; then
            subcom_exec="${curdir}/${val}"
            arg_list="${arg_list} ${val}"
            shift
            break
        elif test -d "${curdir}/${val}" ; then
            curdir="${curdir}/${val}"
            arg_list="${arg_list} ${val}"
            shift
        else
            break
        fi
        prev_val="${val}"
    done
    if test -z "${subcom_exec}" -a -n "${prev_val}" ; then
        if test -f "${curdir}/${prev_val}" -a -x "${curdir}/${prev_val}" ; then
            subcom_exec="${curdir}/${prev_val}"
        fi
    fi

    if test -f "${subcom_exec}" -a -x "${subcom_exec}" ; then
        handle_result "${subcom_exec}" "${arg_list}" "${@}"
    fi

fi

# ---------------------------------------------------------

# Copyright (c) 2020-2026 Random Crew.
#
# Available under ISC License.

# ---------------------------------------------------------
