#! /bin/bash

# default libexecdir used to bootstrap scripts
libexecdir=${GLOBUS_LOCATION}/libexec

# load GRIS common code and initialization
. ${libexecdir}/grid-info-common

######################################################################

_cpu_count=0

### variables used to store probed data
# _cpu_N_vendor=name
# _cpu_N_model=name
# _cpu_N_version=name
# _cpu_N_features=name
# _cpu_N_speed_mhertz=number
# _cpu_N_l2cache_kbytes=number
# _cpu_free1=number
# _cpu_free5=number
# _cpu_free15=number

emit_resource_cpu_summary_attrs ()
{
if [ ! "X${_mds_want_glue}" = "Xtrue" ]
then
cat <<EOF
${_line_class_av}Mds-Cpu-Smp-size: ${_cpu_count}
${_line_class_av}Mds-Cpu-Total-count: ${_cpu_count}
${_line_class_av}Mds-Cpu-Free-1minX100: ${_cpu_free1}
${_line_class_av}Mds-Cpu-Free-5minX100: ${_cpu_free5}
${_line_class_av}Mds-Cpu-Free-15minX100: ${_cpu_free15}
${_line_class_av}Mds-Cpu-Total-Free-1minX100: ${_cpu_free1}
${_line_class_av}Mds-Cpu-Total-Free-5minX100: ${_cpu_free5}
${_line_class_av}Mds-Cpu-Total-Free-15minX100: ${_cpu_free15}
EOF
fi
    i=0
    while [ $i -lt ${_cpu_count} ]
    do
	eval "vendor=\"\${_cpu_${i}_vendor}\""
 	eval "model=\"\${_cpu_${i}_model}\""
 	eval "version=\"\${_cpu_${i}_version}\""
 	eval "features=\"\${_cpu_${i}_features}\""
 	eval "speed=\"\${_cpu_${i}_speed}\""
 	eval "l2cache_size=\"\${_cpu_${i}_l2cache_size}\""
	if [ "X${_mds_want_glue}" = "Xtrue" ]
	then
	cat <<EOF
${_line_class_oc}objectclass: EDTTop
${_line_class_oc}objectclass: ClusterTop
${_line_class_oc}objectclass: Architecture
${_line_class_av}CPUVersion: ${version}
${_line_class_av}CPUModel: ${model}
${_line_class_av}CPUVendor: ${vendor}
EOF
	else
cat <<EOF
${_line_class_av}Mds-Cpu-vendor: ${vendor}
${_line_class_av}Mds-Cpu-model: ${model}
${_line_class_av}Mds-Cpu-version: ${version}
${_line_class_av}Mds-Cpu-features: ${features}
${_line_class_av}Mds-Cpu-speedMHz: ${speed}
${_line_class_av}Mds-Cpu-Cache-l2kB: ${l2cache_size}
EOF
fi
	i=`$EXPR $i + 1`
   done
}

emit_resource_cpu_summary ()
{
cat<<EOF
${_line_class_dn}dn: $1
EOF
if [ ! "X${_mds_want_glue}" = "Xtrue" ]
then
cat<<EOF
${_line_class_oc}objectclass: MdsCpu
${_line_class_oc}objectclass: MdsCpuSmp
${_line_class_oc}objectclass: MdsCpuTotal
${_line_class_oc}objectclass: MdsCpuCache
${_line_class_oc}objectclass: MdsCpuFree
${_line_class_oc}objectclass: MdsCpuTotalFree
EOF
fi
    shift
    while [ $# -gt 0 ]
    do
	echo "$1"
	shift
    done
    emit_resource_cpu_summary_attrs | ${GLOBUS_SH_SORT-sort} \
                                    | ${GLOBUS_SH_UNIQ-uniq}
    echo ""
}

emit_resource_cpu_devices ()
{
    i=0
    while [ $i -lt ${_cpu_count} ]
    do
	eval "vendor=\"\${_cpu_${i}_vendor}\""
 	eval "model=\"\${_cpu_${i}_model}\""
 	eval "version=\"\${_cpu_${i}_version}\""
 	eval "features=\"\${_cpu_${i}_features}\""
 	eval "speed=\"\${_cpu_${i}_speed}\""
 	eval "l2cache_size=\"\${_cpu_${i}_l2cache_size}\""
	if [ ! "X${_mds_want_glue}" = "Xtrue" ]
	then
	cat <<EOF
${_line_class_dn}dn: Mds-device-name=cpu ${i}, $1
${_line_class_oc}objectclass: MdsDevice
${_line_class_oc}objectclass: MdsCpu
${_line_class_oc}objectclass: MdsCpuCache
${_line_class_av}Mds-Device-name: cpu ${i}
${_line_class_av}Mds-Cpu-vendor: ${vendor}
${_line_class_av}Mds-Cpu-model: ${model}
${_line_class_av}Mds-Cpu-version: ${version}
${_line_class_av}Mds-Cpu-features: ${features}
${_line_class_av}Mds-Cpu-speedMHz: ${speed}
${_line_class_av}Mds-Cpu-Cache-l2kB: ${l2cache_size}
EOF
	else
	cat <<EOF
${_line_class_oc}objectclass: EDTTop
${_line_class_oc}objectclass: ClusterTop
${_line_class_oc}objectclass: Architecture
${_line_class_av}CPUVersion: ${version}
${_line_class_av}CPUModel: ${model}
${_line_class_av}CPUVendor: ${vendor}
EOF
	fi
	emit_mds_object_timestamps
	echo 

	i=`$EXPR $i + 1`
    done
}

emit_resource_cpu_descriptions ()
{
    probe_mds_object_timestamps

    timestamps=`emit_mds_object_timestamps`

    if [ "X${_dump_host_object}" = "Xtrue" ]
    then
	emit_resource_cpu_summary "${_suffix}"
    fi

    if [ "X${_dump_devclass_object}" = "Xtrue" ]
    then
	emit_resource_cpu_summary "Mds-Device-Group-name=processors, ${_suffix}" "${_line_class_oc}objectclass: MdsDeviceGroup" "${_line_class_av}Mds-Device-Group-name: processors" "$timestamps"
    fi

    if [ "X${_dump_dev_objects}" = "Xtrue" ]
    then
	emit_resource_cpu_devices "Mds-Device-Group-name=processors, ${_suffix}"
    fi
}

white_strip ()
{
    echo "$@"
}

white_strip_first ()
{
    echo "$1"
}

white_strip_second ()
{
    echo "$2"
}

calculate_freecpus ()
{
    # $1 is cpu count
    # $2 is integer runnable process load
    # $3 is decimal fraction runnable process load

    if [ $3 -gt 0 ]
    then

	case "$3" in
	    08) frac=2 ;;
	    09) frac=9 ;;
	    *) frac=$3 ;;
	esac

	# subtract and carry
	whole=`$EXPR $1 - $2 - 1`
	frac=`$EXPR 100 - $frac`
	if [ $whole -lt 0 ]
	then
	    whole=0
	    frac=0
	elif [ $frac -lt 10 ]
	then
	    frac="0${frac}"
	fi
    else
	whole=`$EXPR $1 - $2`
	frac=00
	if [ $whole -lt 0 ]
	then
		$whole = 0
	fi
    fi
    # print fixed precision result as ${whole}.${frac} * 100
    echo "${whole}${frac}"
}

extract_uptime ()
{
    # $1 is "1" "5" or "15" minute average selector
    # $2 ... $N are uptime info tokens

    select=$1
    shift

    while [ $# -gt 3 ]
    do
	shift
    done

    case "$select" in
	1) : ;;
	5) shift ;;
	15) shift 2 ;;
    esac

    echo "$1"
}

probe_resource_cpufree_uptime ()
{
    uptimeinfo=`${GLOBUS_SH_UPTIME-uptime}`

    IFS="${IFS_save},"

    load1=`extract_uptime 1 $uptimeinfo`
    load5=`extract_uptime 5 $uptimeinfo`
    load15=`extract_uptime 15 $uptimeinfo`

    IFS="${IFS_save}"

    IFS="${IFS_save}."
    _cpu_free1=`calculate_freecpus ${_cpu_count} $load1`
    _cpu_free5=`calculate_freecpus ${_cpu_count} $load5`
    _cpu_free15=`calculate_freecpus ${_cpu_count} $load15`
    IFS="${IFS_save}"
}

