#!/bin/bash
#
# shellcheck disable=SC1091,SC2086,SC2207
#
# Copyright (c) 2023-2026 openmediavault plugin developers
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
#
# version: 0.1.2

export LC_ALL=C.UTF-8

declare -i timeout=180
declare -i i=0
declare -A before_versions

. /usr/share/openmediavault/scripts/helper-functions

# logging location
logDir="/var/log/"
logFile="${logDir}/omv-compose-update.log"

_log()
{
  msg=${1}
  echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] [composeupdate] ${msg}" | tee -a ${logFile} >&2
}

compose="${1}"
if [ -z "${compose}" ]; then
  _log "No compose name set.  Exiting..."
  exit 10
fi
_log "compose :: ${compose}"

# Get docker storage path
dockerStorage=$(omv_config_get "/config/services/compose/dockerStorage")
_log "Docker storage :: ${dockerStorage}"

# get podman setting
podman=$(omv_config_get "/config/services/compose/podman")
_log "podman :: ${podman}"
if [[ "${podman}" == "1" ]]; then
    export DOCKER_HOST="unix:///run/podman/podman.sock"
else
    unset DOCKER_HOST
fi

# Get the shared folder reference and path
sfref=$(omv_config_get "/config/services/compose/sharedfolderref")
if ! omv_isuuid "${sfref}"; then
  _log "No compose sharedfolder set."
  exit 11
fi
sfpath="$(omv_get_sharedfolder_path "${sfref}")"
if [ ! -d "${sfpath}" ]; then
  _log "Shared folder directory does not exist.  Exiting..."
  exit 12
fi
sfpath="${sfpath/%\/}"
sfpath="${sfpath//\/\//\/}"
_log "Compose file path :: ${sfpath}"

# set path for yml and env files
composepath="${sfpath}/${compose}"
yml="${composepath}/${compose}.yml"
if [ ! -f "${yml}" ]; then
  _log "Compose file '${yml}' does not exist.  Exiting..."
  exit 13
fi
_log "Compose file :: ${yml}"

yq="/usr/local/bin/yq"
if [ ! -f "${yq}" ]; then
  _log "'${yq}' does not exist.  Exiting..."
  exit 14
fi

while pgrep -f omv-compose-backup -l > /dev/null; do
  _log "Backup is running.  Waiting ... ${i}"
  sleep 10
  (( i++ ))
  if [ ${i} -gt ${timeout} ]; then
    _log "Timed out waiting.  Exiting."
    exit 15
  fi
done

# save status
status="$(mktemp)"
docker compose ls --all --format json | jq -r ".[] | select(.ConfigFiles | contains(\"${yml}\")) | .Status" | tee "${status}"
_log "status :: $(cat ${status})"

# log current image versions
for image in $(${yq} '.services.[].image | select(. != null)' "${yml}"); do
   version_before=$(docker image ls --format '{{.ID}},{{.Repository}}:{{.Tag}}' "${image}")
  _log "version before :: ${version_before}"
  before_versions["${image}"]="${version_before}"
done

# pull new images
_log "Pulling new images ..."
omv-compose-run "${compose}" pull

# log image versions after update
for image in $(${yq} '.services.[].image | select(. != null)' "${yml}"); do
  version_after=$(docker image ls --format '{{.ID}},{{.Repository}}:{{.Tag}}' "${image}")
  if [ "${version_after}" != "${before_versions["${image}"]}" ]; then
    _log "version after :: ${version_after}"
  fi
done

# recreate containers with new images if running
if grep -q "running" "${status}"; then
  _log "Recreating containers with new images ..."
  omv-compose-run "${compose}" up -d
fi

rm -f "${status}"

_log "Done."

exit 0
