#! /usr/bin/ksh
#
#       @(#)u4ftdev_match	1.1	98/05/27
#
#   Script to find the unique devinfo node matching all the specifed
#   selectors, which can be of two types:
#
#       Static selectors, of the form NAME=VALUE are used to query
#       the architecture configuration database
#
#       Dynamic selectors, of the form [attribute|type:name][!]~pattern
#       are used to select nodes having the matching values for the
#       specified attributes
#

export PATH=${CMSHOME:+"$CMSHOME/lib:"}$PATH

usage()
{
    echo "Usage: ${0##*/} <selector> ..." >&2
    exit 1
}

error()
{
    echo "${0##*/}: $@" >&2
    exit 2
}

list()
{
    for arg
    do
        echo "$arg"
    done
}

if [[ $# -lt 1 ]]
then
    usage
fi

set -A d_sel
set -A s_sel

for p
do
    case "$p" in
    *~*)
        d_sel[${#d_sel[@]}]="$p"
        ;;
    *=*)
        s_sel[${#s_sel[@]}]="$p"
        ;;
    *)
        usage
        ;;
    esac
done

if [[ ${#s_sel[@]} -eq 0 ]]
then
    if [[ ${#d_sel[@]} -eq 0 ]]
    then
        usage
    else
        set -A nodes $(u4ftdev_select '*' "${d_sel[@]}")
    fi
else
    #
    #   If any static selectors were supplied, look up the device path
    #   and check that they identify exactly ONE (static) devpath
    #
    set -A devpaths $(u4ftloc_get_parameter DEVPATH "${s_sel[@]}")
    if [[ ${#devpaths[@]} -lt 1 ]]
    then
        error "no device path specified by arguments"
    elif [[ ${#devpaths[@]} -gt 1 ]]
    then
        error "device path specification ambiguous"
    fi

    #
    #   Now find the devinfo node(s) that match the path ...
    #   Unfortunately, some nodes may still be in PROTO form,
    #   in which case they don't have an address :(
    #   So, we find nodes which have matching paths down to
    #   the nodename component, then check for one with the
    #   correct address.  If there isn't any such node, we
    #   consider nodes with no address.
    #
    address=${devpaths[0]##*@}
    nodepath=${devpaths[0]%@*}
    nodename=${nodepath##*/}
    set -A nodes $(u4ftctl find / $nodename |
                   u4ftdev_select - "path~${nodepath}*")
    set -A CF1_nodes $(list "${nodes[@]}" |
                       u4ftdev_select - "address~${address}")
    set -A CF0_nodes $(list "${nodes[@]}" |
                       u4ftdev_select - "path~${nodepath}")

    if [[ ${#CF1_nodes[@]} -gt 1 ]]
    then
        error "more than one matching node!"
    elif [[ ${#CF1_nodes[@]} -eq 1 ]]
    then
        set -A nodes "${CF1_nodes[0]}"
    else
        set -A nodes "${CF0_nodes[@]}"
    fi
    if [[ ${#d_sel[@]} -gt 0 ]]
    then
        set -A nodes $(list "${nodes[@]}" | u4ftdev_select - "${d_sel[@]}")
    fi
fi

#
#   Finally check that we have uniquely identified ONE devinfo node
#
if [[ ${#nodes[@]} -gt 1 ]]
then
    error "more than one matching node!"
elif [[ ${#nodes[@]} -eq 0 ]]
then
    error "no matching node found"
else
    echo "${nodes[0]}"
fi

