#!/bin/sh
# PCP QA Test No. 1872
# Exercise pmsearch REST API endpoints using curl(1).
# Uses a local SQLite FTS5 search index (no Redis/Valkey).
#
# Copyright (c) 2020,2026 Red Hat.  All Rights Reserved.
#

seq=`basename $0`
echo "QA output created by $seq"

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

which pmsearch >/dev/null 2>&1 || \
    _notrun "pmsearch not installed"
which newhelp >/dev/null 2>&1 || \
    _notrun "newhelp not installed"
newhelp -\? 2>&1 | grep -q '\-S, --search' || \
    _notrun "newhelp not built with SQLite search index support"
[ -x $PCP_BINADM_DIR/pmsearch_daily ] || \
    _notrun "pmsearch_daily not installed"
which pmproxy >/dev/null 2>&1 || \
    _notrun "pmproxy not installed"
which curl >/dev/null 2>&1 || \
    _notrun "curl not installed"
which pmjson >/dev/null 2>&1 || \
    _notrun "pmjson not installed"

_cleanup()
{
    cd $here
    [ -n "$pmproxy_pid" ] && $signal -s TERM $pmproxy_pid
    $sudo rm -rf $tmp $tmp.*
}

status=1	# failure is the default!
signal=$PCP_BINADM_DIR/pmsignal
username=`id -u -n`

trap "_cleanup; exit \$status" 0 1 2 3 15

_filter_elapsed()
{
    sed \
	-e 's/\(\"elapsed\":\) [0-9][0-9]*\.[0-9][0-9]*/\1 XXX/g' \
    #end
}

_filter_info()
{
    sed \
	-e 's/\(\"docs\":\) [0-9][0-9]*/\1 NNN/g' \
	-e 's/\(\"terms\":\) [0-9][0-9]*/\1 NNN/g' \
	-e 's/\(\"records\":\) [0-9][0-9]*/\1 NNN/g' \
    #end
}

# real QA test starts here

archive="$here/archives/sample-labels"
[ -f "$archive.0" ] || _notrun "sample-labels archive not found"
help=$PCP_PMDAS_DIR/sample/help
[ -f "$help" ] || _notrun "sample PMDA help file not found"

# Build a search index using the copy-and-extend strategy:
# base index from help file, then pmsearch_daily copies and appends instances.

echo "=== Build search index ==="
mkdir -p $tmp.share/lib $tmp.var/lib
newhelp -S -o $tmp.share/lib/pmsearch.index $help 2>&1 \
    | sed -e "s,$tmp,TMP,g"
export PCP_VAR_DIR=$tmp.var
export PCP_SHARE_DIR=$tmp.share
$PCP_BINADM_DIR/pmsearch_daily -a $archive
echo "Index built"
echo

# Configure and start pmproxy with search enabled
cat > $tmp.conf <<EOF
[pmproxy]
pcp.enabled = true
http.enabled = true
[pmsearch]
enabled = true
index.path = $tmp.var/lib/pmsearch.index
result.count = 10
EOF

proxyport=`_find_free_port`
echo "proxyport=$proxyport" >>$seq_full
pmproxy -f -U $username -x $seq_full -l $tmp.pmproxy.log \
    -s $tmp.socket -p $proxyport -c $tmp.conf &
pmproxy_pid=$!
_triage_wait_point "cmd: pmproxy -f -U $username -x $seq_full -l $tmp.pmproxy.log -s $tmp.socket -p $proxyport -c $tmp.conf pmproxy => PID $pmproxy_pid"

# check pmproxy has started and is available for requests
pmcd_wait -h localhost@localhost:$proxyport -v -t 5sec

echo "=== /search/text - query for '99' 'random' 'interesting' 'result' ==="
search_terms="99 random interesting result"
for term in $search_terms
do
    url="http://localhost:$proxyport/search/text?query=$term"
    echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
    echo "$url" >> $seq_full
    curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed
done

echo "=== /search/text - no match response ==="

url="http://localhost:$proxyport/search/text?query=bazinga"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/text - dotted query treated as separate terms ==="
# a dotted metric name must search the same terms as the space-separated
# form (dots are term separators, not FTS5 syntax) and must not error.
dot_url="http://localhost:$proxyport/search/text?query=sample.long"
spc_url="http://localhost:$proxyport/search/text?query=sample%20long"
echo "$dot_url" >> $seq_full
echo "$spc_url" >> $seq_full
curl --get --silent "$dot_url" | tee -a $seq_full | pmjson | _filter_elapsed >$tmp.dot
curl --get --silent "$spc_url" | tee -a $seq_full | pmjson | _filter_elapsed >$tmp.spc
if diff $tmp.dot $tmp.spc >/dev/null
then
    echo "sample.long same as 'sample long': yes"
else
    echo "sample.long same as 'sample long': no"
    diff $tmp.dot $tmp.spc
fi

echo "=== /search/text - punctuated query treated as separate terms ==="
# punctuation other than dots (commas, parens, slashes) must also be
# treated as term separators and must not error (e.g. help text searches).
pun_url="http://localhost:$proxyport/search/text?query=sample%2C%20%28long%29%2Fbin"
spc_url="http://localhost:$proxyport/search/text?query=sample%20long%20bin"
echo "$pun_url" >> $seq_full
echo "$spc_url" >> $seq_full
curl --get --silent "$pun_url" | tee -a $seq_full | pmjson | _filter_elapsed >$tmp.pun
curl --get --silent "$spc_url" | tee -a $seq_full | pmjson | _filter_elapsed >$tmp.spc
if diff $tmp.pun $tmp.spc >/dev/null
then
    echo "'sample, (long)/bin' same as 'sample long bin': yes"
else
    echo "'sample, (long)/bin' same as 'sample long bin': no"
    diff $tmp.pun $tmp.spc
fi

echo "=== /search/text - token-less query returns no results ==="

url="http://localhost:$proxyport/search/text?query=."
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/text - query param is required ==="

url="http://localhost:$proxyport/search/text"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent -s -o /dev/null -w "%{http_code}\n" "$url" | tee -a $seq_full

echo "=== /search/text - highlighting is supported on 'name', 'oneline' and 'helptext' by using 'highlight' param ==="

url="http://localhost:$proxyport/search/text?query=domain&highlight=name,oneline,helptext"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=sample&highlight=name"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=counter&highlight=oneline,helptext"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/text  - pagination is supported using cursor params 'limit' and 'offset'"

url="http://localhost:$proxyport/search/text?query=random&limit=1"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=random&limit=1&offset=1"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/text - its possible to query only specific fields (name, oneline, helptext, indom) using 'field' param ==="

url="http://localhost:$proxyport/search/text?query=99&field=name"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=99&field=oneline"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=99&field=helptext"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/text - filtering out fields from response (name, oneline, helptext, type, indom) using 'return' param ==="

url="http://localhost:$proxyport/search/text?query=99&return=name"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=99&return=type"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=99&return=oneline"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=99&return=helptext"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=99&return=indom"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=random&return=name,type,indom"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/text - filtering based on entity type (metric, instance, indom) using 'type' param ==="

url="http://localhost:$proxyport/search/text?query=random&type=metric"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=random&type=indom"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=random&type=instance"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/text?query=random&type=metric,indom"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/suggest - generic request ==="

url="http://localhost:$proxyport/search/suggest?query=sam"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/suggest?query=sample.r"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/suggest - limit is supported"

url="http://localhost:$proxyport/search/suggest?query=sam&limit=2"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/suggest - query param is required ==="

url="http://localhost:$proxyport/search/suggest"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent -s -o /dev/null -w "%{http_code}\n" "$url" | tee -a $seq_full

echo "=== /search/suggest - no match response ==="

url="http://localhost:$proxyport/search/suggest?query=xxx"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/suggest - token-less query returns no results ==="

url="http://localhost:$proxyport/search/suggest?query=."
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/indom - generic request ==="

url="http://localhost:$proxyport/search/indom?query=29.1"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/indom?query=29.3"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/indom - no match response ==="

url="http://localhost:$proxyport/search/indom?query=x"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/indom - query param is required ==="

url="http://localhost:$proxyport/search/indom"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent -s -o /dev/null -w "%{http_code}\n" "$url" | tee -a $seq_full

echo "=== /search/indom  - pagination is supported using cursor params 'limit' and 'offset'"

url="http://localhost:$proxyport/search/indom?query=29.1&limit=2&offset=0"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

url="http://localhost:$proxyport/search/indom?query=29.1&limit=2&offset=2"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_elapsed

echo "=== /search/info ==="

url="http://localhost:$proxyport/search/info"
echo "== verify request - $url" | sed -e "s/$proxyport/PORT/"
echo "$url" >> $seq_full
curl --get --silent "$url" | tee -a $seq_full | pmjson | _filter_info


cat $tmp.pmproxy.log >> $seq_full

# success, all done
status=0
exit
