#   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.

*** Variables ***
${success_return_code}   0


*** Keywords ***
Get Scale Number
    [Arguments]   ${host}   ${username}   ${password}   ${privatekey}   ${application_name}   ${model_name}

    Should Not Be Empty   ${application_name}   ${model_name}
    ${stdout}=   Execute Remote Command Check Rc Return Output   ${host}   ${username}   ${password}   ${privatekey}   juju show-status ${application_name} --format yaml -m ${model_name} | grep scale | awk -F ': ' '{print $2}'
    log   ${stdout}
    [Return]   ${stdout}

Get Model Name
    [Arguments]   ${host}   ${username}   ${password}   ${privatekey}   ${ns_id}   ${kdu_name}

    Should Not Be Empty   ${ns_id}   ${kdu_name}
    ${stdout}=   Execute Remote Command Check Rc Return Output   ${host}   ${username}   ${password}   ${privatekey}   juju models | grep -i ${kdu_name} | grep -i ${ns_id} | cut -f1 -d " "
    log   ${stdout}
    ${model_name}=   Set Variable   ${kdu_name}-${ns_id}
    Should Be Equal As Strings   ${model_name}   ${stdout}
    [Return]   ${stdout}

Get Application Name VDU Level Charm
    [Arguments]   ${host}   ${username}   ${password}   ${privatekey}   ${model_name}   ${vdu_profile_id}   ${ee_name}

    Should Not Be Empty   ${model_name}
    ${stdout}=   Execute Remote Command Check Rc Return Output   ${host}   ${username}   ${password}   ${privatekey}   juju status -m ${model_name} | grep "\\-vdu" | grep -v "*" | grep -i ${vdu_profile_id} | cut -f1 -d " "
    log   ${stdout}
    Should Not Be Empty   ${stdout}
    Should Contain   ${stdout}   ${ee_name}
    [Return]   ${stdout}

Get Application Name NS Level Charm
    [Arguments]   ${host}   ${username}   ${password}   ${privatekey}   ${model_name}   ${charm_name}

    Should Not Be Empty   ${model_name}
    ${stdout}=   Execute Remote Command Check Rc Return Output   ${host}   ${username}   ${password}   ${privatekey}   juju status -m ${model_name} | grep "\\-ns" | grep -v "*" | grep -i ${charm_name} | cut -f1 -d " "
    log   ${stdout}
    Should Not Be Empty   ${stdout}
    [Return]   ${stdout}

Get Application Name VNF Level Charm
    [Arguments]   ${host}   ${username}   ${password}   ${privatekey}   ${model_name}   ${vnf_profile_id}   ${ee_name}

    Should Not Be Empty   ${model_name}
    ${stdout}=   Execute Remote Command Check Rc Return Output   ${host}   ${username}   ${password}   ${privatekey}   juju status -m ${model_name} | grep "\\-vnf" | grep -v "*" | grep -i ${vnf_profile_id} | cut -f1 -d " "
    log   ${stdout}
    Should Not Be Empty   ${stdout}
    Should Contain   ${stdout}   ${ee_name}
    [Return]   ${stdout}