*** 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 providing keywords for CRUD operations over projects with OSM client.
Library   OperatingSystem


*** Variables ***
${SUCCESS_RETURN_CODE}   0


*** Keywords ***
Create Project
    [Documentation]   Create a project in OSM with the name passed as argument, and return the project id.
    [Arguments]   ${project_name}
    Should Not Be Empty   ${project_name}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm project-create ${project_name}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Create Project With Quotas
    [Documentation]   Create a project in OSM with the name and quotas passed as arguments, and return the project id.
    [Arguments]   ${project_name}   ${project_quotas}
    Should Not Be Empty   ${project_name}
    Should Not Be Empty   ${project_quotas}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm project-create ${project_name} --quotas ${project_quotas}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Get Project Quotas
    [Documentation]   Get from OSM a specific quota parameter from the project passed as argument.
    [Arguments]   ${project_name}   ${quotas_name}
    Should Not Be Empty   ${project_name}
    Should Not Be Empty   ${quotas_name}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm project-show ${project_name} | grep '${quotas_name}' | awk -F ',|: ' '{print $2}' | awk '{print $1}'
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Update Project Quotas
    [Documentation]   Update in OSM the quotas of a project with the new quotas passed as arguments.
    [Arguments]   ${project_name}   ${project_quotas}
    Should Not Be Empty   ${project_name}
    Should Not Be Empty   ${project_quotas}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm project-update ${project_name} --quotas ${project_quotas}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}

Update Project Name
    [Documentation]   Update in OSM the name of a project with the new name passed as argument.
    [Arguments]   ${project_name}   ${new_name}
    Should Not Be Empty   ${project_name}
    Should Not Be Empty   ${new_name}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm project-update ${project_name} --name ${new_name}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}

Check If User Is Assigned To Project
    [Documentation]   Check in OSM if a user exists in a project passed as argument.
    [Arguments]   ${user_name}   ${project_name}
    Should Not Be Empty   ${user_name}
    Should Not Be Empty   ${project_name}
    ${rc}   ${stdout}=   Run And Return RC And Output   osm user-show ${user_name} | grep "project_name" | grep "${project_name}"
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}

Create VNFD In Project
    [Documentation]   Onboards a VNF package into an OSM project.
    ...                 Extra parameters (such as 'override') are given to this function in name=value format. These parameters will be appended to the 'osm vnfpkg-create' command with the next syntax: --param_name=param_value
    [Arguments]   ${project_name}   ${vnfd_pkg}   ${project_user}   ${user_password}   @{optional_parameters}
    Should Not Be Empty   ${project_name}
    Should Not Be Empty   ${vnfd_pkg}
    Should Not Be Empty   ${project_user}
    Should Not Be Empty   ${user_password}
    ${osm_pkg_create_command}=   Set Variable   osm --project ${project_name} --user ${project_user} --password ${user_password} vnfpkg-create ${vnfd_pkg}
    FOR   ${param}   IN   @{optional_parameters}
        ${match}   ${param_name}   ${param_value}=   Should Match Regexp   ${param}   (.+)=(.+)   msg=Syntax error in optional parameters
        Log   ${match},${param_name},${param_value}
        ${osm_pkg_create_command}=   Catenate   ${osm_pkg_create_command}   --${param_name}=${param_value}
    END
    ${rc}   ${stdout}=   Run And Return Rc And Output   ${osm_pkg_create_command}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Delete VNFD In Project
    [Documentation]   Deletes a VNF package from an OSM project.
    [Arguments]   ${project_name}   ${vnfd_pkg}   ${project_user}   ${user_password}
    Should Not Be Empty   ${project_name}
    Should Not Be Empty   ${vnfd_pkg}
    Should Not Be Empty   ${project_user}
    Should Not Be Empty   ${user_password}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm --project ${project_name} --user ${project_user} --password ${user_password} vnfpkg-delete ${vnfd_pkg}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}

Remove User From Project
    [Documentation]   Remove a specific user from a specific project in OSM.
    [Arguments]   ${user_name}   ${project_name}
    Should Not Be Empty   ${user_name}
    Should Not Be Empty   ${project_name}
    ${rc}   ${stdout}=   Run And Return RC And Output   osm user-update ${user_name} --remove-project ${project_name}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}

Delete Project
    [Documentation]   Delete from OSM the project passed as argument.
    [Arguments]   ${project_name}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm project-delete ${project_name}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
