#!/bin/bash

#=================================================
# "Low-level" logistic helpers
#=================================================

_RUN_YUNOHOST_CMD() {

    log_debug "Running yunohost $1"

    # Copy the package into the container.
    lxc exec $LXC_NAME -- rm -rf /app_folder
    lxc file push -p -r "$package_path" $LXC_NAME/app_folder --quiet

    # --output-as none is to disable the json-like output for some commands like backup create
    LXC_START "yunohost --output-as none --debug $1" \
        | grep --line-buffered -v --extended-regexp '^[0-9]+\s+.{1,15}DEBUG' \
        | grep --line-buffered -v 'processing action'

    returncode=${PIPESTATUS[0]}
    check_witness_files && return $returncode || return 2
}

_INSTALL_APP () {
    local install_args="$(jq -r '.install_args' $current_test_infos)"
    local preinstall_template="$(jq -r '.preinstall_template' $current_test_infos)"

    # We have default values for domain, user and is_public, but these
    # may still be overwritten by the args ($@)
    for arg_override in "domain=$SUBDOMAIN" "admin=$TEST_USER" "user=$TEST_USER" "is_public=1" "$@"
    do
        key="$(echo $arg_override | cut -d '=' -f 1)"
        value="$(echo $arg_override | cut -d '=' -f 2-)"
        install_args=$(echo $install_args | sed "s@$key=[^&]*\&@$key=$value\&@")
    done

    # Exec the pre-install instruction, if there one
    if [ -n "$preinstall_template" ]
    then
        log_small_title "Running pre-install steps"
        # Copy all the instructions into a script
        local preinstall_script="$TEST_CONTEXT/preinstall.sh"
        echo "$preinstall_template" > "$preinstall_script"
        # Hydrate the template with variables
        sed -i "s/\$USER/$TEST_USER/" "$preinstall_script"
        sed -i "s/\$DOMAIN/$DOMAIN/" "$preinstall_script"
        sed -i "s/\$SUBDOMAIN/$SUBDOMAIN/" "$preinstall_script"
        sed -i "s/\$PASSWORD/$YUNO_PWD/" "$preinstall_script"
        # Copy the pre-install script into the container.
        sudo lxc file push "$preinstall_script" "$LXC_NAME":/preinstall.sh
        # Then execute the script to execute the pre-install commands.
        LXC_START "bash /preinstall.sh"
    fi

    # Install the application in a LXC container
    log_info "Running: yunohost app install --force /app_folder -a $install_args"
    _RUN_YUNOHOST_CMD "app install --force /app_folder -a $install_args"

    local ret=$?
    [ $ret -eq 0 ] && log_debug "Installation successful." || log_error "Installation failed."
    return $ret
}

_LOAD_SNAPSHOT_OR_INSTALL_APP () {

    local check_path="$1"
    local _install_type=$(path_to_install_type $check_path)
    local snapname="snap_${_install_type}install"

    if ! LXC_SNAPSHOT_EXISTS $snapname
    then
        log_warning "Expected to find an existing snapshot $snapname but it doesn't exist yet .. will attempt to create it"
        LOAD_LXC_SNAPSHOT snap0 \
            &&_INSTALL_APP "path=$check_path" \
            && log_debug "(Creating a snapshot for $_install_type installation.)" \
            && CREATE_LXC_SNAPSHOT $snapname
    else
        # Or uses an existing snapshot
        log_debug "(Reusing an existing snapshot for $_install_type installation.)" \
            && LOAD_LXC_SNAPSHOT $snapname
    fi
}


_REMOVE_APP () {
    # Remove an application

    break_before_continue

    log_small_title "Removing the app..."

    # Remove the application from the LXC container
    _RUN_YUNOHOST_CMD "app remove $app_id"

    local ret=$?
    [ "$ret" -eq 0 ] && log_debug "Remove successful." || log_error "Remove failed."
    return $ret
}

_VALIDATE_THAT_APP_CAN_BE_ACCESSED () {

    local check_domain=$1
    local check_path=$2
    local install_type=${3}      # Can be anything or 'private', later used to check if it's okay to end up on the portal
    local app_id_to_check=${4:-$app_id}

    local curl_error=0
    local fell_on_sso_portal=0
    local curl_output=$TEST_CONTEXT/curl_output

    # Not checking this if this ain't relevant for the current app
    this_is_a_web_app || return 0

    log_small_title "Validating that the app can (or cannot) be accessed with its url..."

    # Force a skipped_uris if public mode is not set
    if [ "$install_type" != 'private' ]
    then
        log_debug "Forcing public access using a skipped_uris setting"
        # Add a skipped_uris on / for the app
        _RUN_YUNOHOST_CMD "app setting $app_id_to_check skipped_uris -v \"/\""
        # Regen the config of sso
        _RUN_YUNOHOST_CMD "app ssowatconf"
    fi

    # Try to access to the url in 2 times, with a final / and without
    for i in $(seq 1 2)
    do

        # First time we'll try without the trailing slash,
        # Second time *with* the trailing slash
        local curl_check_path="$(echo $check_path | sed 's@/$@@g')"
        [ $i -eq 1 ] || curl_check_path="$curl_check_path/"

        # Remove the previous curl output
        rm -f "$curl_output"

        local http_code="noneyet"

        local retry=0
        function should_retry() {
            [ "${http_code}" = "noneyet" ] || [ "${http_code}" = "502" ] || [ "${http_code}" = "503" ] || [ "${http_code}" = "504" ]
        }

        while [ $retry -lt 3 ] && should_retry;
        do
            sleep 1

            log_debug "Running curl $check_domain$curl_check_path"

            # Call curl to try to access to the url of the app
            curl --location --insecure --silent --show-error \
                --header "Host: $check_domain" \
                --resolve $DOMAIN:80:$LXC_IP \
                --resolve $DOMAIN:443:$LXC_IP \
                --resolve $SUBDOMAIN:80:$LXC_IP \
                --resolve $SUBDOMAIN:443:$LXC_IP \
                --write-out "%{http_code};%{url_effective}\n" \
                --output "$curl_output" \
                $check_domain$curl_check_path \
                > "./curl_print"

            # Analyze the result of curl command
            if [ $? -ne 0 ]
            then
                log_error "Connection error..."
                curl_error=1
            fi

            http_code=$(cat "./curl_print" | cut -d ';' -f1)

            log_debug "HTTP code: $http_code"

            retry=$((retry+1))
        done

        # Analyze the http code (we're looking for 0xx 4xx 5xx 6xx codes)
        if [ -n "$http_code" ] && echo "0 4 5 6" | grep -q "${http_code:0:1}"
        then
            # If the http code is a 0xx 4xx or 5xx, it's an error code.
            curl_error=1

            # 401 is "Unauthorized", so is a answer of the server. So, it works!
            [ "${http_code}" == "401" ] && curl_error=0

            [ $curl_error -eq 1 ] && log_error "The HTTP code shows an error."
        fi

        # Analyze the output of curl
        if [ -e "$curl_output" ]
        then
            # Print the title of the page
            local page_title=$(grep "<title>" "$curl_output" | cut --delimiter='>' --fields=2 | cut --delimiter='<' --fields=1)
            local page_extract=$(lynx -dump -force_html "$curl_output" | head --lines 20 | tee -a "$complete_log")

            # Check if the page title is neither the YunoHost portail or default nginx page
            if [ "$page_title" = "YunoHost Portal" ]
            then
                log_debug "The connection attempt fall on the YunoHost portal."
                fell_on_sso_portal=1
                # Falling on nginx default page is an error.
            elif [ "$page_title" = "Welcome to nginx on Debian!" ]
            then
                log_error "The connection attempt fall on nginx default page."
                curl_error=1
            fi
        fi

        log_debug "Test url: $check_domain$curl_check_path"
        log_debug "Real url: $(cat "./curl_print" | cut --delimiter=';' --fields=2)"
        log_debug "HTTP code: $http_code"
        log_debug "$test_url_details"
        log_debug "Page title: $page_title"
        log_debug "Page extract:\n$page_extract"

        if [[ $curl_error -ne 0 ]]
        then
            log_warning "Test url: $check_domain$curl_check_path"
            log_warning "Real url: $(cat "./curl_print" | cut --delimiter=';' --fields=2)"
            log_warning "HTTP code: $http_code"
            log_warning "$test_url_details"
            log_warning "Page title: $page_title"
            log_warning "Page extract:\n$page_extract"
        fi
    done

    # Detect the issue alias_traversal, https://github.com/yandex/gixy/blob/master/docs/en/plugins/aliastraversal.md
    # Create a file to get for alias_traversal
    echo "<!DOCTYPE html><html><head>
    <title>alias_traversal test</title>
    </head><body><h1>alias_traversal test</h1>
    If you see this page, you have failed the test for alias_traversal issue.</body></html>" \
    > $TEST_CONTEXT/alias_traversal.html

    sudo lxc file push $TEST_CONTEXT/alias_traversal.html $LXC_NAME/var/www/html/alias_traversal.html

    curl --location --insecure --silent $check_domain$check_path../html/alias_traversal.html \
        | grep "title" | grep --quiet "alias_traversal test" \
        && log_error "Issue alias_traversal detected ! Please see here https://github.com/YunoHost/example_ynh/pull/45 to fix that." \
        && SET_RESULT "failure" alias_traversal

    [ "$curl_error" -eq 0 ] || return 1
    local expected_to_fell_on_portal=""
    [ "$install_type" == "private" ] && expected_to_fell_on_portal=1 || expected_to_fell_on_portal=0
    [ $fell_on_sso_portal -eq $expected_to_fell_on_portal ] && return 0 || return 0
}


#=================================================
# The
# Actual
# Tests
#=================================================

PACKAGE_LINTER () {

    start_test "Package linter"

    # Execute package linter and linter_result gets the return code of the package linter
    ./package_linter/package_linter.py "$package_path" | tee -a "$complete_log"
    ./package_linter/package_linter.py "$package_path" --json | tee -a "$complete_log" > $current_test_results

    return $?
}

TEST_INSTALL () {

    local install_type=$1

    # This is a separate case ... at least from an hystorical point of view ...
    # but it helpers for semantic that the test is a "TEST_INSTALL" ...
    [ "$install_type" = "multi"   ] && { _TEST_MULTI_INSTANCE; return $?; }

    local check_path="/"
    local is_public="1"
    [ "$install_type" = "subdir"  ] && { start_test "Installation in a sub path";      local check_path=/path; }
    [ "$install_type" = "root"    ] && { start_test "Installation on the root";                                }
    [ "$install_type" = "nourl"   ] && { start_test "Installation without url access"; local check_path="";    }
    [ "$install_type" = "private" ] && { start_test "Installation in private mode";    local is_public="0";    }
    local snapname=snap_${install_type}install

    LOAD_LXC_SNAPSHOT snap0

    # Install the application in a LXC container
   _INSTALL_APP "path=$check_path" "is_public=$is_public" \
        && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $SUBDOMAIN $check_path $install_type

    local install=$?

    [ $install -eq 0 ] || return 1

    # Create the snapshot that'll be used by other tests later
    [ "$install_type" != "private" ] \
        && ! LXC_SNAPSHOT_EXISTS $snapname \
        && log_debug "Create a snapshot after app install" \
        && CREATE_LXC_SNAPSHOT $snapname

    # Remove and reinstall the application
    _REMOVE_APP \
        && log_small_title "Reinstalling after removal." \
        &&_INSTALL_APP "path=$check_path" "is_public=$is_public" \
        && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $SUBDOMAIN $check_path $install_type

    return $?
}

_TEST_MULTI_INSTANCE () {

    start_test "Multi-instance installations"

    # Check if an install have previously work
    at_least_one_install_succeeded || return 1

    local check_path=$(default_install_path)

    LOAD_LXC_SNAPSHOT snap0

    log_small_title "First installation: path=$SUBDOMAIN$check_path" \
        && _LOAD_SNAPSHOT_OR_INSTALL_APP "$check_path" \
        && log_small_title "Second installation: path=$DOMAIN$check_path" \
        && _INSTALL_APP "domain=$DOMAIN" "path=$check_path" \
        && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $SUBDOMAIN $check_path \
        && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $DOMAIN $check_path "" ${app_id}__2 \
        && _REMOVE_APP \
        && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $DOMAIN $check_path "" ${app_id}__2

    return $?
}

TEST_UPGRADE () {

    local commit=$1

    if [ "$commit" == "" ]
    then
        start_test "Upgrade from the same version"
    else
        upgrade_name="$(jq -r '.extra.upgrade_name' $current_test_infos)"
        [ -n "$upgrade_name" ] || upgrade_name="commit $commit"
        start_test "Upgrade from $upgrade_name"
    fi

    at_least_one_install_succeeded || return 1

    local check_path=$(default_install_path)

    # Install the application in a LXC container
    log_small_title "Preliminary install..."
    if [ "$commit" == "" ]
    then
        # If no commit is specified, use the current version.
        _LOAD_SNAPSHOT_OR_INSTALL_APP "$check_path"
        local ret=$?
    else
        # Make a backup of the directory
        # and Change to the specified commit
        sudo cp -a "$package_path" "${package_path}_back"
        (cd "$package_path"; git checkout --force --quiet "$commit")

        LOAD_LXC_SNAPSHOT snap0

        # Install the application
       _INSTALL_APP "path=$check_path"
        local ret=$?

        # Then replace the backup
        sudo rm -r "$package_path"
        sudo mv "${package_path}_back" "$package_path"
    fi

    # Check if the install worked
    [ $ret -eq 0 ] || { log_error "Initial install failed... upgrade test ignore"; return 1; }

    log_small_title "Upgrade..."

    # Upgrade the application in a LXC container
    _RUN_YUNOHOST_CMD "app upgrade $app_id -f /app_folder" \
        && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $SUBDOMAIN $check_path

    return $?
}

TEST_PORT_ALREADY_USED () {

    start_test "Port already used"

    # Check if an install have previously work
    at_least_one_install_succeeded || return 1

    local check_port=$1
    local check_path=$(default_install_path)

    LOAD_LXC_SNAPSHOT snap0

    # Build a service with netcat for use this port before the app.
    echo -e "[Service]\nExecStart=/bin/netcat -l -k -p $check_port\n
    [Install]\nWantedBy=multi-user.target" > $TEST_CONTEXT/netcat.service

    sudo lxc file push $TEST_CONTEXT/netcat.service $LXC_NAME/etc/systemd/system/netcat.service

    # Then start this service to block this port.
    LXC_START "sudo systemctl enable netcat & sudo systemctl start netcat"

    # Install the application in a LXC container
   _INSTALL_APP "path=$check_path" "port=$check_port" \
        && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $SUBDOMAIN $check_path

    return $?
}

TEST_BACKUP_RESTORE () {

    # Try to backup then restore the app

    start_test "Backup/Restore"

    # Check if an install have previously work
    at_least_one_install_succeeded || return 1

    local check_path=$(default_install_path)

    # Install the application in a LXC container
    _LOAD_SNAPSHOT_OR_INSTALL_APP "$check_path"

    local ret=$?

    local main_result=0

    # Remove the previous residual backups
    sudo rm -rf ./ynh_backups
    RUN_INSIDE_LXC rm -rf /home/yunohost.backup/archives

    # BACKUP
    # Made a backup if the installation succeed
    if [ $ret -ne 0 ]
    then
        log_error "Installation failed..."
    else
        log_small_title "Backup of the application..."

        # Made a backup of the application
        _RUN_YUNOHOST_CMD "backup create -n Backup_test --apps $app_id"
        ret=$?
    fi

    [ $ret -eq 0 ] || main_result=1

    # Grab the backup archive into the LXC container, and keep a copy
    sudo lxc file pull -r $LXC_NAME/home/yunohost.backup/archives ./ynh_backups

    # RESTORE
    # Try the restore process in 2 times, first after removing the app, second after a restore of the container.
    local j=0
    for j in 0 1
    do
        # First, simply remove the application
        if [ $j -eq 0 ]
        then
            # Remove the application
            _REMOVE_APP

            log_small_title "Restore after removing the application..."

            # Second, restore the whole container to remove completely the application
        elif [ $j -eq 1 ]
        then

            LOAD_LXC_SNAPSHOT snap0

            # Remove the previous residual backups
            RUN_INSIDE_LXC rm -f /rootfs/home/yunohost.backup/archives/*

            # Place the copy of the backup archive in the container.
            sudo lxc file push -r ./ynh_backups/archives/* $LXC_NAME/home/yunohost.backup/archives/

            log_small_title "Restore on a fresh YunoHost system..."
        fi

        # Restore the application from the previous backup
        _RUN_YUNOHOST_CMD "backup restore Backup_test --force --apps $app_id" \
            && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $SUBDOMAIN $check_path

        local ret=$?
        [ $ret -eq 0 ] || main_result=1

        break_before_continue
    done

    return $main_result
}

TEST_CHANGE_URL () {
    # Try the change_url script

    start_test "Change URL"

    # Check if an install have previously work
    at_least_one_install_succeeded || return 1
    this_is_a_web_app || return 0

    log_small_title "Preliminary install..." \
        && _LOAD_SNAPSHOT_OR_INSTALL_APP "/"

    local ret=$?
    [ $ret -eq 0 ] || { return 1; }

    # Try in 6 times !
    # Without modify the domain, root to path, path to path and path to root.
    # And then, same with a domain change
    local i=0
    for i in $(seq 1 6)
    do
        # Same domain, root to path
        if [ $i -eq 1 ]; then
            local new_path=/path
            local new_domain=$SUBDOMAIN

        # Same domain, path to path
        elif [ $i -eq 2 ]; then
            local new_path=/path_2
            local new_domain=$SUBDOMAIN

        # Same domain, path to root
        elif [ $i -eq 3 ]; then
            local new_path=/
            local new_domain=$SUBDOMAIN

        # Other domain, root to path
        elif [ $i -eq 4 ]; then
            local new_path=/path
            local new_domain=$DOMAIN

        # Other domain, path to path
        elif [ $i -eq 5 ]; then
            local new_path=/path_2
            local new_domain=$DOMAIN

        # Other domain, path to root
        elif [ $i -eq 6 ]; then
            local new_path=/
            local new_domain=$DOMAIN
        fi

        log_small_title "Changing the url to $new_domain$new_path..." \
            && _RUN_YUNOHOST_CMD "app change-url $app_id -d $new_domain -p $new_path" \
            && _VALIDATE_THAT_APP_CAN_BE_ACCESSED $new_domain $new_path

        local ret=$?
        [ $ret -eq 0 ] || { return 1; }

        break_before_continue
    done

    return 0
}


ACTIONS_CONFIG_PANEL () {

    test_type=$1

    # Define a function to split a file in multiple parts. Used for actions and config-panel toml
    splitterAA()
    {
        local bound="$1"
        local file="$2"

        # If $2 is a real file
        if [ -e "$file" ]
        then
            # Replace name of the file by its content
            file="$(cat "$file")"
        fi

        local file_lenght=$(echo "$file" | wc --lines | awk '{print $1}')

        bounds=($(echo "$file" | grep --line-number --extended-regexp "$bound" | cut -d':' -f1))

        # Go for each line number (boundary) into the array
        for line_number in $(seq 0 $(( ${#bounds[@]} -1 )))
        do
            # The first bound is the next line number in the array
            # That the low bound on which we cut
            first_bound=$(( ${bounds[$line_number+1]} - 1 ))
            # If there's no next cell in the array, we got -1, in such case, use the lenght of the file.
            # We cut at the end of the file
            test $first_bound -lt 0 && first_bound=$file_lenght
            # The second bound is the current line number in the array minus the next one.
            # The the upper bound in the file.
            second_bound=$(( ${bounds[$line_number]} - $first_bound - 1 ))
            # Cut the file a first time from the beginning to the first bound
            # And a second time from the end, back to the second bound.
            parts[line_number]="$(echo "$file" | head --lines=$first_bound \
                | tail --lines=$second_bound)"
        done
    }

    if [ "$test_type" == "actions" ]
    then
        start_test "Actions"

        toml_file="$package_path/actions.toml"
        if [ ! -e "$toml_file" ]
        then
            log_error "No actions.toml found !"
            return 1
        fi

    elif [ "$test_type" == "config_panel" ]
    then
        start_test "Config-panel"

        toml_file="$package_path/config_panel.toml"
        if [ ! -e "$toml_file" ]
        then
            log_error "No config_panel.toml found !"
            return 1
        fi
    fi

    # Check if an install have previously work
    at_least_one_install_succeeded || return 1

    # Install the application in a LXC container
    log_small_title "Preliminary install..."
    local check_path=$(default_install_path)
    _LOAD_SNAPSHOT_OR_INSTALL_APP "$check_path"

    local main_result=0

    # List first, then execute
    local ret=0
    local i=0
    for i in `seq 1 2`
    do
        # Do a test if the installation succeed
        if [ $ret -ne 0 ]
        then
            log_error "The previous test has failed..."
            continue
        fi

        if [ $i -eq 1 ]
        then
            if [ "$test_type" == "actions" ]
            then
                log_info "> List the available actions..."

                # List the actions
                _RUN_YUNOHOST_CMD "app action list $app_id"
                local ret=$?

                [ $ret -eq 0 ] || main_result=1
                break_before_continue

            elif [ "$test_type" == "config_panel" ]
            then
                log_info "> Show the config panel..."

                # Show the config-panel
                _RUN_YUNOHOST_CMD "app config show-panel $app_id"
                local ret=$?
                [ $ret -eq 0 ] || main_result=1
                break_before_continue

            fi
        elif [ $i -eq 2 ]
        then
            local parts
            if [ "$test_type" == "actions" ]
            then
                log_info "> Execute the actions..."

                # Split the actions.toml file to separate each actions
                splitterAA "^[[:blank:]]*\[[^.]*\]" "$toml_file"
            elif [ "$test_type" == "config_panel" ]
            then
                log_info "> Apply configurations..."

                # Split the config_panel.toml file to separate each configurations
                splitterAA "^[[:blank:]]*\[.*\]" "$toml_file"
            fi

            # Read each part, each action, one by one
            for part in $(seq 0 $(( ${#parts[@]} -1 )))
            do
                local action_config_argument_name=""
                local action_config_argument_type=""
                local action_config_argument_default=""
                local actions_config_arguments_specifics=""
                local nb_actions_config_arguments_specifics=1

                # Ignore part of the config_panel which are only titles
                if [ "$test_type" == "config_panel" ]
                then
                    # A real config_panel part should have a `ask = ` line. Ignore the part if not.
                    if ! echo "${parts[$part]}" | grep --quiet --extended-regexp "^[[:blank:]]*ask ="
                    then
                        continue
                    fi
                    # Get the name of the config. ask = "Config ?"
                    local action_config_name="$(echo "${parts[$part]}" | grep "ask *= *" | sed 's/^.* = \"\(.*\)\"/\1/')"

                    # Get the config argument name "YNH_CONFIG_part1_part2.part3.partx"
                    local action_config_argument_name="$(echo "${parts[$part]}" | grep "^[[:blank:]]*\[.*\]$")"
                    # Remove []
                    action_config_argument_name="${action_config_argument_name//[\[\]]/}"
                    # And remove spaces
                    action_config_argument_name="${action_config_argument_name// /}"

                elif [ "$test_type" == "actions" ]
                then
                    # Get the name of the action. name = "Name of the action"
                    local action_config_name="$(echo "${parts[$part]}" | grep "name" | sed 's/^.* = \"\(.*\)\"/\1/')"

                    # Get the action. [action]
                    local action_config_action="$(echo "${parts[$part]}" | grep "^\[.*\]$" | sed 's/\[\(.*\)\]/\1/')"
                fi

                # Check if there's any [action.arguments]
                # config_panel always have arguments.
                if echo "${parts[$part]}" | grep --quiet "$action_config_action\.arguments" || [ "$test_type" == "config_panel" ]
                then local action_config_has_arguments=1
                else local action_config_has_arguments=0
                fi

                # If there's arguments for this action.
                if [ $action_config_has_arguments -eq 1 ]
                then
                    if [ "$test_type" == "actions" ]
                    then
                        # Get the argument [action.arguments.name_of_the_argument]
                        action_config_argument_name="$(echo "${parts[$part]}" | grep "$action_config_action\.arguments\." | sed 's/.*\.\(.*\)]/\1/')"
                    fi

                    # Get the type of the argument. type = "type"
                    action_config_argument_type="$(echo "${parts[$part]}" | grep "type" | sed 's/^.* = \"\(.*\)\"/\1/')"
                    # Get the default value of this argument. default = true
                    action_config_argument_default="$(echo "${parts[$part]}" | grep "default" | sed 's/^.* = \(.*\)/\1/')"
                    # Do not use true or false, use 1/0 instead
                    if [ "$action_config_argument_default" == "true" ] && [ "$action_config_argument_type" == "boolean" ]; then
                        action_config_argument_default=1
                    elif [ "$action_config_argument_default" == "false" ] && [ "$action_config_argument_type" == "boolean" ]; then
                        action_config_argument_default=0
                    fi

                    if [ "$test_type" == "config_panel" ]
                    then
                        check_process_arguments=""
                        while read line
                        do
                            # Remove all double quotes
                            add_arg="${line//\"/}"
                            # Then add this argument and follow it by :
                            check_process_arguments="${check_process_arguments}${add_arg}:"
                        done < $test_serie_dir/check_process.configpanel_infos #FIXME
                    elif [ "$test_type" == "actions" ]
                    then
                        local check_process_arguments=""
                        while read line
                        do
                            # Remove all double quotes
                            add_arg="${line//\"/}"
                            # Then add this argument and follow it by :
                            check_process_arguments="${check_process_arguments}${add_arg}:"
                        done < $test_serie_dir/check_process.actions_infos #FIXME
                    fi
                    # Look for arguments into the check_process
                    if echo "$check_process_arguments" | grep --quiet "$action_config_argument_name"
                    then
                        # If there's arguments for this actions into the check_process
                        # Isolate the values
                        actions_config_arguments_specifics="$(echo "$check_process_arguments" | sed "s/.*$action_config_argument_name=\(.*\)/\1/")"
                        # And remove values of the following action
                        actions_config_arguments_specifics="${actions_config_arguments_specifics%%\:*}"
                        nb_actions_config_arguments_specifics=$(( $(echo "$actions_config_arguments_specifics" | tr --complement --delete "|" | wc --chars) + 1 ))
                    fi

                    if [ "$test_type" == "config_panel" ]
                    then
                        # Finish to format the name
                        # Remove . by _
                        action_config_argument_name="${action_config_argument_name//./_}"
                        # Move all characters to uppercase
                        action_config_argument_name="${action_config_argument_name^^}"
                        # Add YNH_CONFIG_
                        action_config_argument_name="YNH_CONFIG_$action_config_argument_name"
                    fi
                fi

                # Loop on the number of values into the check_process.
                # Or loop once for the default value
                for j in `seq 1 $nb_actions_config_arguments_specifics`
                do
                    local action_config_argument_built=""
                    if [ $action_config_has_arguments -eq 1 ]
                    then
                        # If there's values into the check_process
                        if [ -n "$actions_config_arguments_specifics" ]
                        then
                            # Build the argument from a value from the check_process
                            local action_config_actual_argument="$(echo "$actions_config_arguments_specifics" | cut -d'|' -f $j)"
                            action_config_argument_built="--args $action_config_argument_name=\"$action_config_actual_argument\""
                        elif [ -n "$action_config_argument_default" ]
                        then
                            # Build the argument from the default value
                            local action_config_actual_argument="$action_config_argument_default"
                            action_config_argument_built="--args $action_config_argument_name=\"$action_config_actual_argument\""
                        else
                            log_warning "> No argument into the check_process to use or default argument for \"$action_config_name\"..."
                            action_config_actual_argument=""
                        fi

                        if [ "$test_type" == "config_panel" ]
                        then
                            log_info "> Apply the configuration for \"$action_config_name\" with the argument \"$action_config_actual_argument\"..."
                        elif [ "$test_type" == "actions" ]
                        then
                            log_info "> Execute the action \"$action_config_name\" with the argument \"$action_config_actual_argument\"..."
                        fi
                    else
                        log_info "> Execute the action \"$action_config_name\"..."
                    fi

                    if [ "$test_type" == "config_panel" ]
                    then
                        # Aply a configuration
                        _RUN_YUNOHOST_CMD "app config apply $app_id $action_config_action $action_config_argument_built"
                        ret=$?
                    elif [ "$test_type" == "actions" ]
                    then
                        # Execute an action
                        _RUN_YUNOHOST_CMD "app action run $app_id $action_config_action $action_config_argument_built"
                        ret=$?
                    fi
                    [ $ret -eq 0 ] || main_result=1
                    break_before_continue
                done
            done
        fi
    done

    return $main_result
}