<?xml version='1.0' standalone='yes'?>
<!DOCTYPE PLUGIN [
  <!ENTITY name "">
  <!ENTITY launch "Connect">
  <!ENTITY author "limetech">
  <!ENTITY version "">
  <!ENTITY pluginURL "">
  <!ENTITY source "/boot/config/plugins/dynamix.my.servers/&name;">
  <!ENTITY TXZ_SHA256 "">
  <!ENTITY NODEJS_VERSION "22.14.0">
  <!-- To get SHA256:
       wget https://nodejs.org/download/release/v22.14.0/node-v22.14.0-linux-x64.tar.xz
       sha256sum node-v22.14.0-linux-x64.tar.xz
  -->
  <!ENTITY NODEJS_FILENAME "node-v&NODEJS_VERSION;-linux-x64.tar.xz">
  <!ENTITY NODEJS_SHA256 "69b09dba5c8dcb05c4e4273a4340db1005abeafe3927efda2bc5b249e80437ec">
  <!ENTITY NODEJS_TXZ "https://nodejs.org/download/release/v&NODEJS_VERSION;/node-v&NODEJS_VERSION;-linux-x64.tar.xz">
  <!ENTITY MAIN_TXZ "">
  <!ENTITY TAG "">
]>

<PLUGIN name="&name;" author="&author;" version="&version;" pluginURL="&pluginURL;"
  launch="&launch;" min="6.9.0-rc1" icon="globe">

  <CHANGES>
    ##a long time ago in a galaxy far far away
    - initial release
  </CHANGES>

  <!-- prevent prod plugin from installing when staging already installed, and vice versa -->
  <FILE Run="/bin/bash" Method="install">
    <INLINE>
      name="&name;" version="&version;" pluginURL="&pluginURL;"
    <![CDATA[
echo "Installing ${name}.plg ${version}"
if [ -f /boot/config/plugins/dynamix.unraid.net.staging.plg ]; then
  echo "ERROR: Cannot proceed with installation"
  echo "Reason: Staging Unraid Connect plugin detected at /boot/config/plugins/dynamix.unraid.net.staging.plg"
  echo "Action required: Please uninstall the existing Unraid Connect Staging plugin first"
  echo "How to fix: Navigate to Plugins > Installed Plugins in the Unraid web GUI and remove the staging plugin"
  echo "Use this URL to reinstall this plugin: ${pluginURL}"
  exit 1
fi
exit 0
]]>
    </INLINE>
  </FILE>

  <!-- gzip check, DNS check, then validate files before doing anything destructive -->
  <FILE Run="/bin/bash" Method="install">
    <INLINE>
      <![CDATA[
# Check available disk space on /usr
echo -n "Checking disk space on /usr... "
FREE_SPACE=$(df -m /usr | awk 'NR==2 {print $4}')
if [ -z "$FREE_SPACE" ]; then
  echo "⚠️ Error: Unable to determine free space on /usr"
  exit 1
fi

if [ "$FREE_SPACE" -lt 300 ]; then
  echo "⚠️ Error: Insufficient disk space on /usr. Need at least 300MB free, only ${FREE_SPACE}MB available"
  exit 1
fi
echo "ok. (${FREE_SPACE}MB free)"

version=
# shellcheck disable=SC1091
source /etc/unraid-version

# ensure gzip is available and executes, is needed by '/etc/rc.d/rc.unraid-api install'
if [ ! -x /bin/gzip ] || ! /bin/gzip -V &>/dev/null; then
  echo "⚠️ Unable to install as gzip is not available on this system. For help, post your diagnostics.zip to a new support thread in the forum."
  exit 1
fi

dnscheck() {
  HOST=$1
  if [ -x /usr/bin/host ] && ! /usr/bin/host -W 10 "${HOST}" &>/dev/null; then
    echo "⚠️ Warning: Your DNS server (${DNS_SERVER1}) is unable to resolve '${HOST}'" 
    DNSERR=yes
  fi
}

# shellcheck disable=SC1090
source <(grep "DNS_SERVER1" /usr/local/emhttp/state/network.ini 2>/dev/null)
DNSERR=no

echo "Checking DNS..."
dnscheck "mothership.unraid.net"

[[ "${DNSERR}" == "yes" && "${DNS_SERVER1}" != "8.8.8.8" ]] && echo "  Recommend navigating to Settings -> Network Settings and changing your DNS server to 8.8.8.8"
# Note: DNS checks will fail if the network is not available at boot. Cannot exit the install when DNS checks fail.

echo
echo "⚠️ Do not close this window yet"
echo
exit 0
]]>
    </INLINE>
  </FILE>
  <FILE Name="/boot/config/plugins/dynamix.my.servers/&NODEJS_FILENAME;">
    <URL>&NODEJS_TXZ;</URL>
    <SHA256>&NODEJS_SHA256;</SHA256>
  </FILE>
  <FILE Run="/bin/bash" Method="install">
    <INLINE>
      NODE_FILE="&NODEJS_FILENAME;"
      <![CDATA[
        # Check if the Node.js archive exists
        if [[ ! -f "/boot/config/plugins/dynamix.my.servers/${NODE_FILE}" ]]; then
          echo "Node.js archive not found at /boot/config/plugins/dynamix.my.servers/${NODE_FILE}"
          exit 1
        fi

        # Perform a dry run to verify the archive is valid
        if ! tar --strip-components=1 -tf "/boot/config/plugins/dynamix.my.servers/${NODE_FILE}" > /dev/null; then
          echo "Node.js archive is corrupt or invalid"
          exit 1
        fi

        # Define the target directory for Node.js
        NODE_DIR="/usr/local/node"

        # Create the target directory if it doesn't exist
        mkdir -p "${NODE_DIR}" || { echo "Failed to create ${NODE_DIR}"; exit 1; }

        # Extract the archive to the target directory
        if ! tar --strip-components=1 -xf "/boot/config/plugins/dynamix.my.servers/${NODE_FILE}" -C "${NODE_DIR}"; then
          echo "Failed to extract Node.js archive"
          exit 1
        fi

        # Remove all node js archives from the flashdrive that do not match the expected version
        find /boot/config/plugins/dynamix.my.servers/ -name "node-v*-linux-x64.tar.xz" ! -name "${NODE_FILE}" -delete


        echo "Node.js installation successful"

        exit 0
      ]]>
    </INLINE>
  </FILE>

  <!-- download main txz -->
  <FILE Name="&source;.txz">
    <URL>&MAIN_TXZ;</URL>
    <SHA256>&TXZ_SHA256;</SHA256>
  </FILE>

  <FILE Run="/bin/bash" Method="remove">
    <INLINE>
      <![CDATA[
version=
# shellcheck disable=SC1091
source /etc/unraid-version

# Undo some activation / partner setup
source /usr/local/emhttp/plugins/dynamix.my.servers/scripts/activation_code_remove

# Run cleanup operations
echo "Performing cleanup operations..."
/usr/bin/php /usr/local/emhttp/plugins/dynamix.my.servers/scripts/cleanup_operations.php

echo
echo "⚠️ Do not close this window yet"
echo

exit 0
]]>
    </INLINE>
  </FILE>

  <!-- Cleanup for install on unsupported OS -->
  <FILE Run="/usr/bin/php" Method="install">
    <INLINE>
      <![CDATA[
<?php
// Check Unraid version
$version = @parse_ini_file('/etc/unraid-version', true)['version'];

// Check if this is a supported version
// - Must be 6.12.0 or higher
// - Must not be a 6.12.0 beta/rc version
$is_stable_6_12_or_higher = version_compare($version, '6.12.0', '>=') && !preg_match('/^6\\.12\\.0-/', $version);

if ($is_stable_6_12_or_higher) {
  echo "Running on supported version {$version}, skipping cleanup\n";
  exit(0);
}

echo "Running on unsupported version {$version}, performing cleanup\n";
echo "Running cleanup operations...\n";
include_once("/usr/local/emhttp/plugins/dynamix.my.servers/scripts/cleanup_operations.php");

exit(0);
]]>
    </INLINE>
  </FILE>

  <!-- uninstall existing plugin during update or removal -->
  <FILE Run="/bin/bash" Method="install remove">
    <INLINE>
    <![CDATA[
echo "Uninstalling existing plugin"
version=
# shellcheck disable=SC1091
source /etc/unraid-version

echo
echo "⚠️ Do not close this window yet"
echo

if [ -e /etc/rc.d/rc.unraid-api ]; then
  touch /tmp/restore-files-dynamix-unraid-net
  # stop flash backup
  /etc/rc.d/rc.flash_backup stop &>/dev/null
  # stop the api gracefully
  /etc/rc.d/rc.unraid-api stop &>/dev/null
  # Stop newer clients
  unraid-api stop
  # forcibly stop older clients
  kill -9 `pidof unraid-api` &>/dev/null
  # Find all PIDs referencing main.js and kill them, excluding grep process
  pids=$(ps aux | grep "node /usr/local/unraid-api/dist/main.js" | grep -v grep | awk '{print $2}')
  for pid in $pids; do
    kill -9 $pid
  done
  # uninstall the api
  rm -rf /usr/local/unraid-api
  rm -rf /var/run/unraid-api.sock
fi
    ]]>
    </INLINE>
  </FILE>

  <FILE Run="/bin/bash" Method="remove">
    <INLINE>
      MAINNAME="&name;"
      <![CDATA[
      echo "Removing Plugin"
      [[ -f "/var/log/packages/${MAINNAME}" ]] && removepkg --terse "${MAINNAME}"
      ]]>
    </INLINE>
  </FILE>

  <!-- uninstall existing plugin during removal -->
  <FILE Run="/bin/bash" Method="install remove">
    <INLINE>
    <![CDATA[
    echo "Restoring Files"

if [ -f /tmp/restore-files-dynamix-unraid-net ]; then
  # restore stock files
  FILES_TO_RESTORE=(
    "/usr/local/emhttp/plugins/dynamix/DisplaySettings.page"
    "/usr/local/emhttp/plugins/dynamix/Registration.page"
    "/usr/local/emhttp/plugins/dynamix/include/DefaultPageLayout.php"
    "/usr/local/emhttp/plugins/dynamix/include/ProvisionCert.php"
    "/usr/local/emhttp/plugins/dynamix/include/UpdateDNS.php"
    "/usr/local/emhttp/plugins/dynamix/include/ReplaceKey.php"
    "/usr/local/emhttp/plugins/dynamix/include/Wrappers.php"
    "/usr/local/emhttp/plugins/dynamix.plugin.manager/Downgrade.page"
    "/usr/local/emhttp/plugins/dynamix.plugin.manager/Update.page"
    "/usr/local/emhttp/plugins/dynamix.plugin.manager/include/ShowChanges.php"
    "/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/showchanges"
    "/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck"
    "/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php"
    "/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php"
    "/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page"
    "/usr/local/emhttp/plugins/dynamix.my.servers/MyServers.page"
    "/usr/local/emhttp/plugins/dynamix.my.servers/Registration.page"
    "/usr/local/emhttp/plugins/dynamix.my.servers/include/myservers1.php"
    "/usr/local/emhttp/plugins/dynamix.my.servers/include/myservers2.php"
    "/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php"
    "/usr/local/emhttp/plugins/dynamix.my.servers/data/server-state.php"
    "/usr/local/emhttp/plugins/dynamix.my.servers/include/reboot-details.php"
    "/usr/local/emhttp/plugins/dynamix.my.servers/include/translations.php"
  )

  for FILE in "${FILES_TO_RESTORE[@]}"; do
    [[ -f "$FILE-" ]] && mv -f "$FILE-" "$FILE"
  done
  
  DIR=/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components
  # certain instances where the directory is not present and others where it is, ensure we delete it before we restore it
  if [[ -d "$DIR" ]]; then
    rm -rf "$DIR"
  fi
  if [[ -d "$DIR-" ]]; then
    mv -f "$DIR-" "$DIR"
  fi
  # delete plugin files from flash drive and OS
  rm -f /boot/config/plugins/dynamix.my.servers/.gitignore
  rm -f /etc/rc.d/rc.unraid-api
  rm -f /etc/rc.d/rc.flash_backup
  rm -rf /usr/local/sbin/unraid-api
  rm -rf /usr/local/bin/unraid-api
  rm -rf /usr/local/emhttp/plugins/dynamix.unraid.net
  rm -rf /usr/local/emhttp/plugins/dynamix.unraid.net.staging
  rm -f /etc/rc.d/rc6.d/K10_flash_backup
  rm -f /var/log/gitcount
  rm -f /var/log/gitflash
  rm -f /var/log/gitratelimit
  rm -f /usr/local/emhttp/state/flashbackup.ini
  rm -f /usr/local/emhttp/state/myservers.cfg
  # delete any legacy files that may exist
  rm -rf /boot/config/plugins/dynamix.my.servers/libvirt.node
  rm -rf /boot/config/plugins/dynamix.my.servers/segfault-handler.node
  rm -rf /boot/config/plugins/dynamix.my.servers/wc
  rm -f /boot/config/plugins/Unraid.net/unraid-api.tgz
  rm -f /boot/config/plugins/Unraid.net/.gitignore
  rm -f /boot/config/plugins/dynamix.my.servers/unraid-api.tgz
  rm -rf /boot/config/plugins/Unraid.net/webComps
  rm -rf /boot/config/plugins/Unraid.net/wc
  rm -f /usr/local/emhttp/webGui/javascript/vue.js
  rm -f /usr/local/emhttp/webGui/javascript/vue.min.js
  rm -rf /usr/local/emhttp/webGui/webComps
  rm -rf /usr/local/emhttp/webGui/wc
  # clean up our optional makestate modifications in rc.nginx (on 6.9 and 6.10.0-rc[12])
  sed -i '/scripts\/makestate/d' /etc/rc.d/rc.nginx
  # clean up extra origin for robots.txt
  sed -i '#robots.txt any origin/d' /etc/rc.d/rc.nginx
  rm /tmp/restore-files-dynamix-unraid-net
fi
exit 0
]]>
    </INLINE>
  </FILE>

  <!-- install all the things -->
  <FILE Run="/bin/bash" Method="install">
    <INLINE>
      TAG="&TAG;" MAINTXZ="&source;.txz"
    <![CDATA[
appendTextIfMissing() {
  FILE="$1" TEXT="$2"
  if test -f "${FILE}" && ! grep -q "${TEXT}" "${FILE}" &>/dev/null; then
    echo "${TEXT}">>"${FILE}"
  fi
}
source /root/.bashrc


version=
# shellcheck disable=SC1091
source /etc/unraid-version
# exit this install block on isUnsupportedVersion
# must be 6.12.0 or higher (not 6.12.0-[beta|rc]x)
if [[ "${version:0:3}" == "6.9" || "${version:0:4}" == "6.10" || "${version:0:4}" == "6.11" || "${version:0:7}" == "6.12.0-" ]]; then
  echo
  echo "⚠️ Please uninstall this plugin or upgrade to a newer version of Unraid to enjoy Unraid Connect"
  echo
  echo "✅ It is safe to close this window"
  echo

  DIR="/usr/local/emhttp/plugins/dynamix.unraid.net" && [[ ! -d "$DIR" ]] && mkdir "$DIR"
cat << EOF > "$DIR/README.md"
**Unraid Connect**

Please uninstall this plugin or upgrade to a newer version of Unraid to enjoy Unraid Connect
EOF
  # exit 0 or else the original plugin will be reinstalled at boot
  exit 0
fi

echo
echo "⚠️ Do not close this window yet"
echo

# NOTE: any 'exit 1' after this point will result in a broken install

# Loop through the array of preserveFilesDirs and perform actions
# string param format
# "{move|copy|move_dir}:{path}:{preventDowngrade|skip}"
# move: move the file to a backup file
# copy: copy the file to a backup file
# move_dir: move the directory to a backup directory
# preventDowngrade: during plg install, if the file exists, do not overwrite it if the plg manifest version is less than the installed webgui version
# skip: do not perform any action if there is a manifest version difference
preserveFilesDirs=(
  "move:/usr/local/emhttp/plugins/dynamix/Registration.page:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix/include/UpdateDNS.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix/include/ReplaceKey.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/Downgrade.page:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/Update.page:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/MyServers.page:skip"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page:skip"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/Registration.page:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/include/myservers1.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/include/myservers2.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php:preventDowngrade"
  "move_dir:/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components:move_dir:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/data/server-state.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/include/reboot-details.php:preventDowngrade"
  "move:/usr/local/emhttp/plugins/dynamix.my.servers/include/translations.php:preventDowngrade"
  "copy:/usr/local/emhttp/plugins/dynamix/include/DefaultPageLayout.php:preventDowngrade"
)

preserveAction() {
    local action="$1"
    local path="$2"
    local preventType="$3" # preventDowngrade or skip

    if [[ "$action" == "move" ]]; then
        [[ -f "$path" ]] && mv -f "$path" "$path-"
    elif [[ "$action" == "copy" ]]; then
        [[ -f "$path" ]] && cp -f "$path" "$path-"
    elif [[ "$action" == "move_dir" ]]; then
        [[ -d "$path" ]] && mv -f "$path" "$path-"
    fi
}

# Loop through the array of preserveFilesDirs and perform actions
for obj in "${preserveFilesDirs[@]}"
do
    IFS=':' read -r action path preventType <<< "$obj"
    preserveAction "$action" "$path" "$preventType"
done

# patch DefaultPageLayout.php
# search text:       <?=_('Version')?>: <?=_var($var,'version','?')?><?=$notes?>
#                    <?=_('Version')?>: <?=$var['version']?><?=$notes?>
# replacement text:  <unraid-i18n-host><unraid-header-os-version></unraid-header-os-version></unraid-i18n-host>
FILE=/usr/local/emhttp/plugins/dynamix/include/DefaultPageLayout.php
# get line number matching the search text
# shellcheck disable=SC2016
LINENUM=$(grep -n '<?=_('"'Version'"')?>: <?=_var($var,'"'version'"','"'?'"')?><?=$notes?>' "$FILE" | cut -d : -f 1)
# shellcheck disable=SC2016
[[ -z $LINENUM ]] && LINENUM=$(grep -n '<?=_('"'Version'"')?>: <?=$var\['"'version'"']?><?=$notes?>' "$FILE" | cut -d : -f 1)
if [[ -n $LINENUM ]]; then
  # backup the file so it can be restored later
  cp -f "$FILE" "$FILE-"
  # sed should work, but it is very difficult to escape the search text
  # instead, make a new file containing everything before LINENUM, then the replacement text, then everything after LINENUM
  head -$((LINENUM-1)) "$FILE"> "$FILE~"
  echo '<unraid-i18n-host><unraid-header-os-version></unraid-header-os-version></unraid-i18n-host>' >> "$FILE~"
  tail +$((LINENUM+1)) "$FILE">> "$FILE~"

  # disable these lines: <?$readme = @file_get_contents("$docroot/plugins/unRAIDServer/README.md",false,null,0,20)?:''?>
  #                      <?$readme = @file_get_contents("$docroot/plugins/unRAIDServer/README.md",false,null,0,20)??'';?>
  #                      <?$readme = @file_get_contents("$docroot/plugins/unRAIDServer/README.md",false,null,0,20);?>
  # by replacing with:   <?$readme ="removed by Connect";?>
  sed -i '/unRAIDServer\/README\.md/c\<?$readme ="removed by Connect";?>' "$FILE~"

  mv -f "$FILE~" "$FILE"
fi

# patch: showchanges, starting with 6.11.0-rc1
#        ShowChanges.php, in 6.10
# search text:       $valid = ['/var/tmp/','/tmp/plugins/'];
# replacement text:  $valid = ['/var/tmp/','/tmp/plugins/','/boot/previous'];
FILES=(/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/showchanges /usr/local/emhttp/plugins/dynamix.plugin.manager/include/ShowChanges.php)
for FILE in "${FILES[@]}"; do
  if test -f "${FILE}" && ! grep -q "'/boot/previous'" "${FILE}" &>/dev/null; then
    # backup the file so it can be restored later
    cp -f "$FILE" "$FILE-"
    sed -i '/$valid = \[/c$valid = ['"'/var/tmp/'"','"'/tmp/plugins/'"','"'/boot/previous'"'];' "$FILE"
  fi
done

# remove keys.limetechnology.com from hosts file
# brings older versions of Unraid in sync with 6.12.12
# no need to restore original file on uninstall
if grep -q "keys.lime-technology.com" /etc/hosts &>/dev/null; then sed -i "/keys.lime-technology.com/d" /etc/hosts &>/dev/null; fi

# patch ProvisionCert.php
# search text:       curl_init("https://keys.lime-technology.com/account/ssl/provisionwildcard")
#                    curl_init("https://keys.lime-technology.com/account/ssl/$endpoint");
# prepend text:      see $ADDTEXT4
ADDTEXT4=$(
cat <<'END_HEREDOC'
// added by Unraid Connect
// ensure keys.lime-technology.com is not hard-coded in the hosts file
exec('if grep -q "keys.lime-technology.com" /etc/hosts &>/dev/null; then sed -i "/keys.lime-technology.com/d" /etc/hosts &>/dev/null; fi');
END_HEREDOC
)
FILE=/usr/local/emhttp/plugins/dynamix/include/ProvisionCert.php
# get line number matching the search text
# shellcheck disable=SC2016
LINENUM=$(grep -n 'curl_init("https://keys.lime-technology.com/account/ssl/provisionwildcard")' "$FILE" | cut -d : -f 1)
[[ -z $LINENUM ]] && LINENUM=$(grep -n 'curl_init("https://keys.lime-technology.com/account/ssl/$endpoint")' "$FILE" | cut -d : -f 1)
if [[ -n $LINENUM ]]; then
  # backup the file so it can be restored later
  cp -f "$FILE" "$FILE-"
  # sed should work, but it is very difficult to escape
  # instead, make a new file containing everything before LINENUM, then the new text, then everything including and after LINENUM
  head -$((LINENUM-1)) "$FILE"> "$FILE~"
  echo "$ADDTEXT4">> "$FILE~"
  echo "">> "$FILE~"
  tail +$LINENUM "$FILE">> "$FILE~"
  mv -f "$FILE~" "$FILE"
fi

# move settings on flash drive
CFG_OLD=/boot/config/plugins/Unraid.net
CFG_NEW=/boot/config/plugins/dynamix.my.servers
[[ -d "$CFG_OLD" ]] && [[ ! -d "$CFG_NEW" ]] && mv "$CFG_OLD" "$CFG_NEW"


# relax restrictions on built-in Firefox so it can sign in to Unraid Connect
# brings older versions of Unraid in sync with 6.12.0
# no need to restore original file on uninstall
# note: if file is modified while Firefox is open it will have no effect, reboot to change the file before Firefox is loaded
# note: prior to 6.12, file will only exist if system is booted in GUI Mode
FILE=/usr/share/mozilla/firefox/9n35r0i1.default/user.js
if [[ -f "$FILE" ]]; then
  cp -f "$FILE" "$FILE-"
  appendTextIfMissing "${FILE}" 'user_pref("privacy.firstparty.isolate", false);'
  appendTextIfMissing "${FILE}" 'user_pref("javascript.options.asmjs", true);'
  appendTextIfMissing "${FILE}" 'user_pref("javascript.options.wasm", true);'
fi

# fix update.htm to work in an iframe
# brings older versions of Unraid in sync with 6.12.0
# no need to restore original file on uninstall, will cause issues if uninstall from within an iframe
FILE=/usr/local/emhttp/update.htm
if test -f "${FILE}" && grep -q "top.document" "${FILE}" &>/dev/null; then
  cp -f "$FILE" "$FILE-"
  sed -i 's/top.document/parent.document/gm' "${FILE}"
fi

# fix logging.htm (openBox) to work in an iframe
# brings older versions of Unraid in sync with 6.12.0
# no need to restore original file on uninstall
FILE=/usr/local/emhttp/logging.htm
if test -f "${FILE}" && grep -q "top.Shadowbox" "${FILE}" &>/dev/null; then
  cp -f "$FILE" "$FILE-"
  sed -i 's/top.Shadowbox/parent.Shadowbox/gm' "${FILE}"
fi

# ensure _var() is defined, brings older versions of Unraid in sync with 6.12.0
FILE=/usr/local/emhttp/plugins/dynamix/include/Wrappers.php
if test -f "${FILE}" && ! grep -q "function _var" "${FILE}" &>/dev/null; then
ADDTEXT1=$(
cat <<'END_HEREDOC'
// backported by Unraid Connect
function _var(&$name, $key=null, $default='') {
  return is_null($key) ? ($name ?? $default) : ($name[$key] ?? $default);
}
END_HEREDOC
)
fi
# ensure my_logger() is defined, brings older versions of Unraid in sync with 6.13.0
if test -f "${FILE}" && ! grep -q "function my_logger" "${FILE}" &>/dev/null; then
ADDTEXT2=$(
cat <<'END_HEREDOC'
// backported by Unraid Connect
// ensure params passed to logger are properly escaped
function my_logger($message, $logger='webgui') {
  exec('logger -t '.escapeshellarg($logger).' -- '.escapeshellarg($message));
}
END_HEREDOC
)
fi
# ensure http_get_contents() is defined, brings older versions of Unraid in sync with 6.13.0
if test -f "${FILE}" && ! grep -q "function http_get_contents" "${FILE}" &>/dev/null; then
ADDTEXT3=$(
cat <<'END_HEREDOC'
// backported by Unraid Connect
// Original PHP code by Chirp Internet: www.chirpinternet.eu
// Please acknowledge use of this code by including this header.
// https://www.the-art-of-web.com/php/http-get-contents/
// Modified for Unraid
/**
 * Fetches URL and returns content
 * @param string $url The URL to fetch
 * @param array $opts Array of options to pass to curl_setopt()
 * @param array $getinfo Empty array passed by reference, will contain results of curl_getinfo and curl_error
 * @return string|false $out The fetched content
 */
function http_get_contents(string $url, array $opts = [], array &$getinfo = NULL) {
  $ch = curl_init();
  if(isset($getinfo)) {
    curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
  }
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
  curl_setopt($ch, CURLOPT_TIMEOUT, 45);
  curl_setopt($ch, CURLOPT_ENCODING, "");
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  curl_setopt($ch, CURLOPT_REFERER, "");
  curl_setopt($ch, CURLOPT_FAILONERROR, true);
  curl_setopt($ch, CURLOPT_USERAGENT, 'Unraid');
  if(is_array($opts) && $opts) {
    foreach($opts as $key => $val) {
      curl_setopt($ch, $key, $val);
    }
  }
  $out = curl_exec($ch);
  if (curl_errno($ch) == 23) {
    // error 23 detected, try CURLOPT_ENCODING = "deflate"
    curl_setopt($ch, CURLOPT_ENCODING, "deflate");
    $out = curl_exec($ch);
  }
  if (isset($getinfo)) {
    $getinfo = curl_getinfo($ch);
  }
  if ($errno = curl_errno($ch)) {
    $msg = "Curl error $errno: " . (curl_error($ch) ?: curl_strerror($errno)) . ". Requested url: '$url'";
    if(isset($getinfo)) {
      $getinfo['error'] = $msg;
    }
    my_logger($msg, "http_get_contents");
  }
  curl_close($ch);
  return $out;
}
END_HEREDOC
)
fi
if [[ -n "${ADDTEXT1}" || -n "${ADDTEXT2}" || -n "${ADDTEXT3}" ]]; then
  TMP="$FILE.$RANDOM"
  cp -f "$FILE" "$TMP"
  cp -f "$FILE" "$FILE-"
  # delete last line of the file if it contains `?>`
  if test $( tail -n 1 "${TMP}" ) = '?>' ; then 
    sed -i '$ d' "${TMP}"
  fi
  [[ -n "${ADDTEXT1}" ]] && echo "${ADDTEXT1}">>"${TMP}"
  [[ -n "${ADDTEXT2}" ]] && echo "${ADDTEXT2}">>"${TMP}"
  [[ -n "${ADDTEXT3}" ]] && echo "${ADDTEXT3}">>"${TMP}"
  echo "?>">>"${TMP}"
  mv "${TMP}" "${FILE}"
fi

# Restore the upgradepkg binary if it exists and the original does not
if [[ -f /sbin/upgradepkg- && ! -f /sbin/upgradepkg ]]; then
  cp -f /sbin/upgradepkg- /sbin/upgradepkg
fi

# install the main txz
upgradepkg --install-new --reinstall "${MAINTXZ}"

# confirm an expected file now exists
# WARNING: failure here results in broken install
[[ ! -f /usr/local/emhttp/plugins/dynamix.my.servers/scripts/gitflash_log ]] && echo "⚠️ files missing from main txz" && exit 1

if [[ -n "$TAG" && "$TAG" != "" ]]; then
  printf -v sedcmd 's@^\*\*Unraid Connect\*\*@**Unraid Connect (%s)**@' "$TAG"
  sed -i "${sedcmd}" "/usr/local/emhttp/plugins/dynamix.unraid.net/README.md"
fi

echo
echo "⚠️ Do not close this window yet"
echo

# setup env
echo "env=\"production\"">/boot/config/plugins/dynamix.my.servers/env


# Use myservers.cfg values to help prevent conflicts when installing
CFG=/boot/config/plugins/dynamix.my.servers/myservers.cfg
# shellcheck disable=SC1090
source <(grep 'email\|apikey="unraid_' "${CFG}" 2>/dev/null)
CFG_CLEANED=0
# If user is signed in but has no apikey, or if the apikey is not 64 chars, wipe the [remote] section from the cfg
if ([[ -n "${email}" && (-z "${apikey}" || "${#apikey}" -ne "64") ]]); then
  # remove only the [remote] section
  awk '{
  if($0 ~ /\[remote\]/){output="off"; next}
  if($0 ~ /\[/){output="on"; print; next}
  if(output == "on"){print}
  }' "${CFG}">"${CFG}-new" && mv "${CFG}-new" "${CFG}" CFG_CLEANED=1
  echo "⚠️ Automatically signed out of Unraid.net"
fi

# configure flash backup to stop when the system starts shutting down
[[ ! -d /etc/rc.d/rc6.d ]] && mkdir /etc/rc.d/rc6.d
[[ ! -h /etc/rc.d/rc0.d ]] && ln -s /etc/rc.d/rc6.d /etc/rc.d/rc0.d
[[ ! -h /etc/rc.d/rc6.d/K10_flash_backup  ]] && ln -s /etc/rc.d/rc.flash_backup /etc/rc.d/rc6.d/K10_flash_backup

# allow webgui to be iframed only on Connect dashboard, only applies to 6.10+
# if needed, restart nginx before installing the unraid-api
CHANGED=no
FILE=/etc/nginx/nginx.conf
# brings older versions of Unraid in sync with 6.12.0
if grep -q "SAMEORIGIN" "${FILE}"; then
  CHANGED=yes
  cp "$FILE" "$FILE-" OLD="add_header X-Frame-Options 'SAMEORIGIN';" NEW="add_header Content-Security-Policy \"frame-ancestors 'self' https://connect.myunraid.net/\";"
  sed -i "s#${OLD}#${NEW}#" "${FILE}"
fi

FILE=/etc/rc.d/rc.nginx
# brings older versions of Unraid in sync with 6.12.0
if ! grep -q "#robots.txt any origin" "${FILE}"; then
  CHANGED=yes
  cp "$FILE" "$FILE-" FIND="location = \/robots.txt {"
  # escape tabs and spaces
  ADD="\	\ \ \ \ add_header Access-Control-Allow-Origin *; #robots.txt any origin"
  sed -i "/${FIND}/a ${ADD}" "${FILE}"
fi

preventDowngradeAction() {
    local action="$1"
    local path="$2"
    local preventType="$3" # preventDowngrade or skip

    # if skip, do nothing
    if [[ "$preventType" == "skip" ]]; then
        return
    fi

    # restore the "backup" but keep the original backup for the uninstall plg script
    # otherwise, the uninstall script will NOT be able to restore the original file
    if [[ "$action" == "move" || "$action" == "copy" ]]; then
        [[ -f "$path-" ]] && cp -f "$path-" "$path"
    elif [[ "$action" == "move_dir" ]]; then
        # if directory exists rm the original and copy the backup
        # glob expansion via "$path-/"* …yes the * is necessary as we want to copy the contents of the directory
        [[ -d "$path-" ]] && rm -rf "$path" && mkdir "$path" && cp -rf "$path-/"* "$path"
    fi
}

# Extract "ts" values from both files
plgWebComponentPath="/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components"
backupWebComponentPath="/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components-"
plgManifestTs=$(find "$plgWebComponentPath" -name manifest.json -exec jq -r '.ts' {} \; 2>/dev/null)
webguiManifestTs=$(find "$backupWebComponentPath" -name manifest.json -exec jq -r '.ts' {} \; 2>/dev/null)

# Compare the "ts" values and return the file path of the higher value
if [[ "$webguiManifestTs" -gt "$plgManifestTs" ]]; then
    # Loop through the array of preserveFilesDirs and perform actions
    for obj in "${preserveFilesDirs[@]}"
    do
        IFS=':' read -r action path preventType <<< "$obj"
        preventDowngradeAction "$action" "$path" "$preventType"
    done
    echo "♻️ Reverted to stock web component files"
fi

echo
echo "⚠️ Do not close this window yet"
echo

# Activation and partner setup
# - Must come after the web component timestamp check to avoid potentially targeting the wrong JS during this setup
source /usr/local/emhttp/plugins/dynamix.my.servers/scripts/activation_code_setup

flash="/boot/config/plugins/dynamix.my.servers"
[[ ! -d "${flash}" ]] && echo "Please reinstall the Unraid Connect plugin" && exit 1
[[ ! -f "${flash}/env" ]] && echo 'env=production' >"${flash}/env"
env=production
# shellcheck disable=SC1091
source "${flash}/env"
# Install the API to /usr/local/unraid-api
api_base_directory="/usr/local/unraid-api"
unraid_binary_path="/usr/local/bin/unraid-api"

# Stop old process
if [[ -f "/usr/local/bin/unraid-api/unraid-api" ]]; then
  /usr/local/bin/unraid-api/unraid-api stop
  rm -rf /usr/local/bin/unraid-api
elif [[ -f "${unraid_binary_path}" ]]; then
  ${unraid_binary_path} stop
fi

# Kill any remaining unraid-api processes
pkill -9 unraid-api

# Create log directory (PM2 will not start without it)
mkdir -p /var/log/unraid-api

# Copy env file
cp "${api_base_directory}/.env.${env}" "${api_base_directory}/.env"

# bail if expected file does not exist
[[ ! -f "${api_base_directory}/package.json" ]] && echo "unraid-api install failed" && exit 1

# Create Symlink from /usr/local/unraid-api/dist/cli.js to /usr/local/bin/unraid-api
# Ensure we're linking the file, not the directory, by checking it exists first
if [[ -f "${api_base_directory}/dist/cli.js" ]]; then
  ln -sf "${api_base_directory}/dist/cli.js" "${unraid_binary_path}"
else
  echo "Error: ${api_base_directory}/dist/cli.js does not exist" && exit 1
fi

# Ensure unraid-api exists
if [[ ! -f "${unraid_binary_path}" ]]; then
  echo "Error: unraid-api binary not found at ${unraid_binary_path}" && exit 1
fi


# Create symlink to unraid-api binary (to allow usage elsewhere)
ln -sf /usr/local/node/bin/node /usr/local/bin/node
ln -sf ${unraid_binary_path} /usr/local/sbin/unraid-api
ln -sf ${unraid_binary_path} /usr/bin/unraid-api


logger "Starting flash backup (if enabled)"
echo "/etc/rc.d/rc.flash_backup start" | at -M now &>/dev/null
. /root/.bashrc

logger "Starting Unraid API"
${unraid_binary_path} start

if [[ "${CHANGED}" == "yes" ]]; then
  if /etc/rc.d/rc.nginx status &>/dev/null; then
    # if nginx is running, reload it to enable the changes above
    # note: if this is being installed at boot, nginx will not yet be running
    echo ""
    echo "✅ Installation complete, now reloading web server - it is safe to close this window"
    /etc/rc.d/rc.nginx reload &>/dev/null
  fi
else
  echo
  echo "✅ Installation is complete, it is safe to close this window"
  echo
fi

exit 0
]]>
    </INLINE>
  </FILE>

  <FILE Run="/bin/bash" Method="remove">
    <INLINE>
      <![CDATA[
version=
# shellcheck disable=SC1091
source /etc/unraid-version

echo
echo "✅ Uninstall is complete, it is safe to close this window"
echo

exit 0
]]>
    </INLINE>
  </FILE>

</PLUGIN>
