#!/bin/bash
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
{%- import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %}
{%- set SUPPORTED_PACKAGES = salt['pillar.get']('elasticfleet:packages', default=ELASTICFLEETDEFAULTS.elasticfleet.packages, merge=True) %}
{%- set AUTO_UPGRADE_INTEGRATIONS = salt['pillar.get']('elasticfleet:config:auto_upgrade_integrations', default=false) %}

. /usr/sbin/so-elastic-fleet-common

curl_output=$(curl -s -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http://localhost:5601/)
if [ $? -ne 0 ]; then
    echo "Error: Failed to connect to Kibana."
    exit 1
fi

IFS=$'\n'
agent_policies=$(elastic_fleet_agent_policy_ids)
if [ $? -ne 0 ]; then
    echo "Error: Failed to retrieve agent policies."
    exit 1
fi

default_packages=({% for pkg in SUPPORTED_PACKAGES %}"{{ pkg }}"{% if not loop.last %} {% endif %}{% endfor %})

ERROR=false
for AGENT_POLICY in $agent_policies; do
    if ! integrations=$(elastic_fleet_integration_policy_names "$AGENT_POLICY"); then
        # this script upgrades default integration packages, exit 1 and let salt handle retrying
        exit 1
    fi
    for INTEGRATION in $integrations; do
        if ! [[ "$INTEGRATION" == "elastic-defend-endpoints" ]] && ! [[ "$INTEGRATION" == "fleet_server-"* ]]; then
            # Get package name so we know what package to look for when checking the current and latest available version
            if ! PACKAGE_NAME=$(elastic_fleet_integration_policy_package_name "$AGENT_POLICY" "$INTEGRATION"); then
                exit 1
            fi
            {%- if not AUTO_UPGRADE_INTEGRATIONS %}
            if [[ " ${default_packages[@]} " =~ " $PACKAGE_NAME " ]]; then
            {%- endif %}
                # Get currently installed version of package
                attempt=0
                max_attempts=3
                while [ $attempt -lt $max_attempts ]; do
                    if PACKAGE_VERSION=$(elastic_fleet_integration_policy_package_version "$AGENT_POLICY" "$INTEGRATION") && AVAILABLE_VERSION=$(elastic_fleet_package_latest_version_check "$PACKAGE_NAME"); then
                        break
                    fi
                    attempt=$((attempt + 1))
                done
                if [ $attempt -eq $max_attempts ]; then
                    echo "Error: Failed getting $PACKAGE_VERSION or $AVAILABLE_VERSION"
                    exit 1
                fi

                # Get integration ID
                if ! INTEGRATION_ID=$(elastic_fleet_integration_id "$AGENT_POLICY" "$INTEGRATION"); then
                    exit 1
                fi

                if [[ "$PACKAGE_VERSION" != "$AVAILABLE_VERSION" ]]; then
                    # Dry run of the upgrade
                    echo ""
                    echo "Current $PACKAGE_NAME package version ($PACKAGE_VERSION) is not the same as the latest available package ($AVAILABLE_VERSION)..."
                    echo "Upgrading $INTEGRATION..."
                    echo "Starting dry run..."
                    if ! DRYRUN_OUTPUT=$(elastic_fleet_integration_policy_dryrun_upgrade "$INTEGRATION_ID"); then
                        exit 1
                    fi
                    DRYRUN_ERRORS=$(echo "$DRYRUN_OUTPUT" | jq .[].hasErrors)

                    # If no errors with dry run, proceed with actual upgrade
                    if [[ "$DRYRUN_ERRORS" == "false" ]]; then
                        echo "No errors detected. Proceeding with upgrade..."
                        if ! elastic_fleet_integration_policy_upgrade "$INTEGRATION_ID"; then
                            echo "Error: Upgrade failed for $PACKAGE_NAME with integration ID '$INTEGRATION_ID'."
                            ERROR=true
                            continue
                        fi
                    else
                        echo "Errors detected during dry run for $PACKAGE_NAME policy upgrade..."
                        ERROR=true
                        continue
                    fi
                fi
            {%- if not AUTO_UPGRADE_INTEGRATIONS %}
            fi
            {%- endif %}
        fi
    done
done
if [[ "$ERROR" == "true" ]]; then
    exit 1
fi
echo
