<?xml version='1.0' standalone='yes'?>
<!DOCTYPE PLUGIN [
  <!ENTITY name "webgui-pr-1042">
  <!ENTITY version "2026.06.23.0822">
  <!ENTITY author "unraid">
  <!ENTITY pluginURL "https://preview.dl.unraid.net/pr-plugins/pr-1042/webgui-pr-1042.plg">
  <!ENTITY tarball "webgui-pr-1042-2026.06.23.0822.tar.gz">
  <!ENTITY sha256 "cf0a8ceb45a554448ef218685f6007d7e43ea7a1193ef1864d349e4fea8f3702">
  <!ENTITY pr "1042">
  <!ENTITY commit "aa74ab613">
  <!ENTITY github "https://github.com/unraid/webgui">
]>

<PLUGIN name="&name;-&version;"
        author="&author;"
        version="&version;"
        pluginURL="&pluginURL;"
        min="7.1.0"
        icon="wrench"
        support="&github;/pull/&pr;">

<CHANGES>
##&version;
- Test build for PR #&pr; (commit &commit;)
- Applies the PR's changes as a patch, so multiple PR test plugins can be
  installed together as long as they do not edit the same lines
- Changes are reversed when the plugin is removed
</CHANGES>

<!-- FILE sections run in the listed order -->

<!-- If this is an update: reverse the previously applied patch / restore binaries first -->
<FILE Run="/bin/bash" Method="install">
<INLINE>
<![CDATA[
echo "===================================="
echo "WebGUI PR Test Plugin Update"
echo "===================================="
echo "Version: 2026.06.23.0822"
echo ""

PLUGIN_DIR="/boot/config/plugins/webgui-pr-1042"
BACKUP_DIR="$PLUGIN_DIR/backups"
MANIFEST="$PLUGIN_DIR/installed_files.txt"
PATCH_APPLIED="$PLUGIN_DIR/applied.patch"
PAYLOAD="$PLUGIN_DIR/payload"

mkdir -p "$PLUGIN_DIR" "$BACKUP_DIR"

# Roll back THIS plugin's previous text changes by restoring the shipped
# originals, then re-applying the other still-installed PR plugins so their
# changes survive. (Deterministic: does not depend on reverse-patch context.)
if [ -f "$PLUGIN_DIR/text_files.txt" ]; then
    echo "Rolling back previous text changes..."
    while IFS= read -r sys; do
        [ -n "$sys" ] || continue
        SYS="/$sys"
        if [ -f "$PLUGIN_DIR/orig/$sys" ]; then
            mkdir -p "$(dirname "$SYS")"; cp -f "$PLUGIN_DIR/orig/$sys" "$SYS"
        else
            rm -f "$SYS"   # file was newly added by this PR
        fi
    done < "$PLUGIN_DIR/text_files.txt"
    for other in /boot/config/plugins/webgui-pr-*; do
        [ -d "$other" ] || continue
        [ "$other" == "$PLUGIN_DIR" ] && continue
        [ -f "$other/applied.patch" ] || continue
        # Non-blocking: all patches passed dry-run at install time, so failure here
        # is a rare edge case worth surfacing rather than swallowing.
        if ! patch -p1 -d / --forward --batch < "$other/applied.patch" >/dev/null 2>&1; then
            echo "⚠️  Warning: could not re-apply $(basename "$other")'s changes; reinstall it or reboot to restore them"
            logger -t webgui-pr "re-apply of $(basename "$other") patch failed during $(basename "$PLUGIN_DIR") rollback"
        fi
        # Re-applying the patch recreates any new files at 0644; restore modes.
        if [ -f "$other/modes.txt" ]; then
            while read -r mode sys; do
                [ -n "$mode" ] && [ -n "$sys" ] || continue
                [ -e "/$sys" ] && chmod "$mode" "/$sys"
            done < "$other/modes.txt"
        fi
    done
fi
rm -f "$PATCH_APPLIED"
rm -rf "$PLUGIN_DIR/orig"
rm -f "$PLUGIN_DIR/modes.txt"
: > "$PLUGIN_DIR/text_files.txt"

# Restore any previously installed binary files
if [ -f "$MANIFEST" ]; then
    echo "Restoring binary files from previous version..."
    while IFS='|' read -r system_file backup_file; do
        [ -n "$system_file" ] || continue
        if [ "$backup_file" == "NEW" ]; then
            [ -e "$system_file" ] && { echo "Removing PR file: $system_file"; rm -f "$system_file"; }
        elif [ -f "$backup_file" ]; then
            echo "Restoring original: $system_file"
            cp -fp "$backup_file" "$system_file"
        fi
    done < "$MANIFEST"
fi

: > "$MANIFEST"
rm -rf "$PAYLOAD"
echo "Ready for fresh install of PR files."
]]>
</INLINE>
</FILE>

<!-- Create plugin directories -->
<FILE Run="/bin/bash" Method="install">
<INLINE>
<![CDATA[
echo "===================================="
echo "WebGUI PR Test Plugin Installation"
echo "===================================="
echo "Version: 2026.06.23.0822"
echo "PR: #1042"
echo "Commit: aa74ab613"
echo ""
mkdir -p /boot/config/plugins/webgui-pr-1042/backups
echo "Created plugin directories"
]]>
</INLINE>
</FILE>

<!-- Download tarball from GitHub/R2 -->
<FILE Name="/boot/config/plugins/webgui-pr-1042/webgui-pr-1042-2026.06.23.0822.tar.gz">
<URL>https://preview.dl.unraid.net/pr-plugins/pr-1042/webgui-pr-1042-2026.06.23.0822.tar.gz</URL>
<SHA256>&sha256;</SHA256>
</FILE>

<!-- Apply patch + install binaries -->
<FILE Run="/bin/bash" Method="install">
<INLINE>
<![CDATA[
PLUGIN_DIR="/boot/config/plugins/webgui-pr-1042"
BACKUP_DIR="$PLUGIN_DIR/backups"
MANIFEST="$PLUGIN_DIR/installed_files.txt"
PATCH_APPLIED="$PLUGIN_DIR/applied.patch"
TARBALL="$PLUGIN_DIR/webgui-pr-1042-2026.06.23.0822.tar.gz"
PAYLOAD="$PLUGIN_DIR/payload"

echo "Extracting payload..."
rm -rf "$PAYLOAD"
mkdir -p "$PAYLOAD"
tar -xzf "$TARBALL" -C "$PAYLOAD"
: > "$MANIFEST"

# ---- Text changes: apply unified diff -------------------------------------
if [ -s "$PAYLOAD/pr.patch" ]; then
    echo "Checking patch applies cleanly..."
    if ! patch -p1 -d / --dry-run --forward --batch < "$PAYLOAD/pr.patch" > /tmp/pr_patch_check.txt 2>&1; then
        echo ""
        echo "❌ Install aborted: this PR's changes do not apply cleanly."
        echo "   Another installed PR plugin likely edits the same lines."
        echo "------------------------------------------------------------"
        grep -Ei 'FAILED|can.t find file|hunk' /tmp/pr_patch_check.txt || cat /tmp/pr_patch_check.txt
        echo "------------------------------------------------------------"
        echo "Remove the conflicting webgui-pr-* plugin and try again."
        rm -f /tmp/pr_patch_check.txt
        exit 1
    fi
    rm -f /tmp/pr_patch_check.txt
    echo "Applying patch..."
    patch -p1 -d / --forward --batch < "$PAYLOAD/pr.patch"
    cp -f "$PAYLOAD/pr.patch" "$PATCH_APPLIED"
    # Persist the originals + file list so removal can rebuild deterministically
    rm -rf "$PLUGIN_DIR/orig"
    [ -d "$PAYLOAD/orig" ] && cp -a "$PAYLOAD/orig" "$PLUGIN_DIR/orig"
    [ -f "$PAYLOAD/text_files.txt" ] && cp -f "$PAYLOAD/text_files.txt" "$PLUGIN_DIR/text_files.txt"
    echo "✅ Patch applied"
fi

# ---- Binary changes: whole-file replace (cannot be merged) -----------------
if [ -s "$PAYLOAD/binary_files.txt" ]; then
    # Guard: a binary may only be managed by one PR plugin at a time
    while IFS= read -r sys; do
        [ -n "$sys" ] || continue
        for other in /boot/config/plugins/webgui-pr-*; do
            [ -d "$other" ] || continue
            [ "$other" == "$PLUGIN_DIR" ] && continue
            if [ -f "$other/installed_files.txt" ] && grep -q "^/$sys|" "$other/installed_files.txt"; then
                echo "❌ Install aborted: binary /$sys is already managed by $(basename "$other")."
                echo "   Remove that plugin first: plugin remove $(basename "$other").plg"
                exit 1
            fi
        done
    done < "$PAYLOAD/binary_files.txt"

    while IFS= read -r sys; do
        [ -n "$sys" ] || continue
        SYS="/$sys"
        SRC="$PAYLOAD/binary/$sys"
        BK="$BACKUP_DIR/$(echo "$sys" | tr '/' '_')"
        mkdir -p "$(dirname "$SYS")"
        if [ -f "$SYS" ] && [ ! -f "$BK" ]; then cp -p "$SYS" "$BK"; fi
        if [ -f "$BK" ]; then echo "$SYS|$BK" >> "$MANIFEST"; else echo "$SYS|NEW" >> "$MANIFEST"; fi
        cp -f "$SRC" "$SYS"
        echo "Installed binary: $SYS"
    done < "$PAYLOAD/binary_files.txt"
fi

# ---- Restore file modes ----------------------------------------------------
# Unified diffs carry no permission bits, so patched/new text files land 0644
# and lose any exec bit. Re-apply the modes recorded at build time. Persist
# modes.txt so rolling back another PR plugin can restore them too.
if [ -f "$PAYLOAD/modes.txt" ]; then
    cp -f "$PAYLOAD/modes.txt" "$PLUGIN_DIR/modes.txt"
    while read -r mode sys; do
        [ -n "$mode" ] && [ -n "$sys" ] || continue
        [ -e "/$sys" ] && chmod "$mode" "/$sys"
    done < "$PAYLOAD/modes.txt"
    echo "✅ File modes restored"
fi

echo ""
echo "✅ Installation complete for PR #1042"
echo "⚠️  This is a TEST plugin — remove it before applying production updates"
echo "⚠️  A reboot may be required for some changes to take effect"
]]>
</INLINE>
</FILE>

<!-- Add a banner to warn user this plugin is installed -->
<FILE Name="/usr/local/emhttp/plugins/webgui-pr-1042/Banner-1042.page">
<INLINE>
<![CDATA[
Menu='Buttons'
Link='nav-user'
---
<script>
  $(function() {
    // Check for updates (non-dismissible)
    caPluginUpdateCheck("webgui-pr-1042.plg", {noDismiss: true},function(result){
      try {
        let json = JSON.parse(result);
        if ( ! json.version ) {
          addBannerWarning("Note: webgui-pr-1042 has either been merged or removed");
        }
      } catch(e) {}
    });

    // Create banner with uninstall link (nondismissible)
    let bannerMessage = "Modified GUI installed via <b>webgui-pr-1042</b> plugin. " +
                       "<a onclick='uninstallPRPlugin()' style='cursor: pointer; text-decoration: underline;'>Click here to uninstall</a>";

    // true = warning style, true = non-dismissible
    addBannerWarning(bannerMessage, true, true);

    // Define uninstall function
    window.uninstallPRPlugin = function() {
      swal({
        title: "Uninstall PR Test Plugin?",
        text: "This will reverse all of this PR's changes and remove the test plugin.",
        type: "warning",
        showCancelButton: true,
        confirmButtonText: "Yes, uninstall",
        cancelButtonText: "Cancel",
        closeOnConfirm: false,
        showLoaderOnConfirm: true
      }, function(isConfirm) {
        if (isConfirm) {
          openPlugin("plugin remove webgui-pr-1042.plg", "Removing PR Test Plugin", "", "refresh");
        }
      });
    };
  });
</script>
]]>
</INLINE>
</FILE>

<!-- Removal script -->
<FILE Run="/bin/bash" Method="remove">
<INLINE>
<![CDATA[
echo "===================================="
echo "WebGUI PR Test Plugin Removal"
echo "===================================="
echo ""

PLUGIN_DIR="/boot/config/plugins/webgui-pr-1042"
MANIFEST="$PLUGIN_DIR/installed_files.txt"
PATCH_APPLIED="$PLUGIN_DIR/applied.patch"

# Restore this plugin's text files to their shipped originals, then re-apply the
# other still-installed PR plugins so their (non-overlapping) changes survive.
if [ -f "$PLUGIN_DIR/text_files.txt" ]; then
    echo "Restoring text files..."
    while IFS= read -r sys; do
        [ -n "$sys" ] || continue
        SYS="/$sys"
        if [ -f "$PLUGIN_DIR/orig/$sys" ]; then
            mkdir -p "$(dirname "$SYS")"; cp -f "$PLUGIN_DIR/orig/$sys" "$SYS"
        else
            rm -f "$SYS"   # file was newly added by this PR
        fi
    done < "$PLUGIN_DIR/text_files.txt"
    for other in /boot/config/plugins/webgui-pr-*; do
        [ -d "$other" ] || continue
        [ "$other" == "$PLUGIN_DIR" ] && continue
        [ -f "$other/applied.patch" ] || continue
        # Non-blocking: all patches passed dry-run at install time, so failure here
        # is a rare edge case worth surfacing rather than swallowing.
        if ! patch -p1 -d / --forward --batch < "$other/applied.patch" >/dev/null 2>&1; then
            echo "⚠️  Warning: could not re-apply $(basename "$other")'s changes; reinstall it or reboot to restore them"
            logger -t webgui-pr "re-apply of $(basename "$other") patch failed during $(basename "$PLUGIN_DIR") rollback"
        fi
    done
    echo "✅ Text changes restored"
fi

# Restore binary files
if [ -f "$MANIFEST" ]; then
    echo "Restoring binary files..."
    while IFS='|' read -r system_file backup_file; do
        [ -n "$system_file" ] || continue
        if [ "$backup_file" == "NEW" ]; then
            [ -e "$system_file" ] && { echo "Removing new file: $system_file"; rm -f "$system_file"; }
        elif [ -f "$backup_file" ]; then
            echo "Restoring: $system_file"
            cp -fp "$backup_file" "$system_file"
        else
            echo "⚠️  Missing backup for: $system_file"
        fi
    done < "$MANIFEST"
fi

echo "Cleaning up plugin files..."
rm -rf "/usr/local/emhttp/plugins/webgui-pr-1042"
rm -rf "$PLUGIN_DIR"

echo ""
echo "✅ Plugin removed successfully"
echo "⚠️  A reboot may be required to fully clear all changes"
]]>
</INLINE>
</FILE>

</PLUGIN>
