*** Comments ***
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.


*** Settings ***
Documentation   Library to obtain metrics from Prometheus.

Library   String
Library   Collections
Library   OperatingSystem
Library   RequestsLibrary


*** Variables ***
${TIMEOUT}   30
${MAX_RETRIES}   1
${PROMETHEUS_HOST}   %{PROMETHEUS_HOSTNAME=UNKNOWN}
${PROMETHEUS_PORT}   %{PROMETHEUS_PORT=9090}
${PROMETHEUS_USER}   %{PROMETHEUS_USER=""}
${PROMETHEUS_PASSWORD}   %{PROMETHEUS_PASSWORD=""}


*** Keywords ***
Set Testsuite Prometheus Variables
    [Documentation]   Set Testsuite Prometheus Variables to be used in subsequent test cases

    IF   '${PROMETHEUS_HOST}' == 'UNKNOWN'
        ${local_prometheus_host}=   Get Environment Variable   OSM_HOSTNAME
        IF   '${local_prometheus_host}'.startswith('nbi.')
            ${local_prometheus_host}=   Replace String   ${local_prometheus_host}   nbi.   prometheus.
        END
        Set Suite Variable   ${PROMETHEUS_HOST}   ${local_prometheus_host}
        Set Suite Variable   ${PROMETHEUS_PORT}   80
    END
    Set Suite Variable   ${PROMETHEUS_URL}   http://${PROMETHEUS_HOST}:${PROMETHEUS_PORT}
    Log   ${PROMETHEUS_PORT}
    Log   ${PROMETHEUS_HOST}
    Log   ${PROMETHEUS_URL}
    Log   ${PROMETHEUS_USER}
    Log   ${PROMETHEUS_PASSWORD}

Get Metric
    [Documentation]   Get the instant value of a metric from Prometheus using multiple filter parameters.
    ...                 The filter parameters are given to this function in key=value format (one argument per key/value pair).
    ...                 Fails if the metric is not found or has multiple values.
    ...                 Examples of execution:
    ...                     \${metric}=   Get Metric   \${prometheus_url}   ${prometheus_password}   \${metric}
    ...                     \${metric}=   Get Metric   \${prometheus_url}   ${prometheus_password}   \${metric}   \${param1}=\${value1}   \${param2}=\${value2}
    [Arguments]   ${prometheus_url}   ${prometheus_user}   ${prometheus_password}   ${metric}   @{filter_parameters}
    Log   ${prometheus_url}
    Log   ${prometheus_user}
    Log   ${prometheus_password}
    Log   ${metric}
    Log   ${filter_parameters}
    ${filter}=   Set Variable   ${EMPTY}
    FOR   ${param}   IN   @{filter_parameters}
        ${match}   ${param_name}   ${param_value}=   Should Match Regexp   ${param}   (.+)=(.+)   msg=Syntax error in filter parameters
        Log   ${match},${param_name},${param_value}
        ${filter}=   Catenate   SEPARATOR=   ${filter}   ${param_name}="${param_value}",
    END
    ${resp}=   Execute Prometheus Instant Query   ${prometheus_url}   ${prometheus_user}   ${prometheus_password}   query=${metric}{${filter}}
    Log   ${resp}
    ${result_list}=   Convert To List   ${resp["data"]["result"]}
    ${results}=   Get Length   ${result_list}
    Should Not Be Equal As Numbers   0   ${results}   msg=Metric ${metric} not found   values=false
    Should Be Equal As Integers   1   ${results}   msg=Metric ${metric} with multiple values   values=false
    RETURN   ${result_list[0]["value"][1]}

Execute Prometheus Instant Query
    [Documentation]   Execute a Prometheus Instant Query using HTTP API.
    ...                 Return an inline json with the result of the query.
    ...                 The requested URL is the next: \${prometheus_url}/api/v1/query?\${querystring}
    [Arguments]   ${prometheus_url}   ${prometheus_user}   ${prometheus_password}   ${querystring}
    Log   ${prometheus_url}
    Log   ${prometheus_user}
    Log   ${prometheus_password}
    Log   ${querystring}
    ${auth}=   IF   '${prometheus_password}' != '${EMPTY}'   Create List   ${prometheus_user}   ${prometheus_password}   ELSE   Set Variable   None
    Create Session   prometheus   ${prometheus_url}   timeout=${TIMEOUT}   max_retries=${MAX_RETRIES}   verify=false   auth=${auth}
    ${resp}=   GET On Session   prometheus   /api/v1/query?${querystring}   timeout=${TIMEOUT}
    Status Should Be   200   ${resp}
    RETURN   ${resp.json()}
