#!/bin/bash
# postinst script for #PACKAGE#
#
# see: dh_installdeb(1)

set -e

# Begin vars.sh
#!/bin/bash
# DO NOT EDIT
# This file is regenerated each run.
# If you want to add or change a variable, edit debify/settings.json and the vars hashref

source /etc/os-release
export OBS_REPO="x${NAME}_${VERSION_ID}"
if ls debian/*.install &> /dev/null; then
    perl -pi -e 's/\${env:OBS_REPO}/$ENV{OBS_REPO}/' debian/*.install
fi

export DEB_INSTALL_ROOT="/usr/src/packages/BUILD/debian/tmp"
export DEB_SOURCE_ROOT="/usr/src/packages/BUILD/debian/SOURCES_FROM_SPEC"
export RPM_SOURCE_DIR="/usr/src/packages/BUILD/debian/SOURCES_FROM_SPEC"
export __isa_bits="64"
export __isa_name="x86"
export __sourcedir=""
export _bindir="/opt/cpanel//root/usr/bin"
export _datadir="/opt/cpanel//root/usr/share"
export _defaultdocdir="/opt/cpanel//root/usr/share/doc"
export _docdir="/opt/cpanel//root/usr/share/doc"
export _exec_prefix="/opt/cpanel//root/usr"
export _includedir="/opt/cpanel//root/usr/include"
export _infodir="/opt/cpanel//root/usr/share/info"
export _isa=""
export _lib="lib64"
export _libdir="/opt/cpanel//root/usr/lib64"
export _libexecdir="/opt/cpanel//root/usr/libexec"
export _localstatedir="/opt/cpanel//root/var"
export _mandir="/opt/cpanel//root/usr/share/man"
export _prefix="/opt/cpanel//root/usr"
export _root_bindir="/opt/cpanel//root/usr/bin"
export _root_datadir="/opt/cpanel//root/usr/share"
export _root_exec_prefix="/opt/cpanel//root/usr"
export _root_includedir="/opt/cpanel//root/usr/include"
export _root_infodir="/opt/cpanel//root/usr/share/info"
export _root_initddir="/opt/cpanel//root/etc/rc.d/init.d"
export _root_libdir="/opt/cpanel//root/usr/lib64"
export _root_libexecdir="/opt/cpanel//root/usr/libexec"
export _root_localstatedir="/opt/cpanel//root/var"
export _root_mandir="/opt/cpanel//root/usr/share/man"
export _root_prefix="/opt/cpanel//root/usr"
export _root_sbindir="/opt/cpanel//root/usr/sbin"
export _root_sharedstatedir="/opt/cpanel//root/usr/com"
export _root_sysconfdir="/opt/cpanel//root/etc"
export _sbindir="/opt/cpanel//root/usr/sbin"
export _scl_prefix="/opt/cpanel"
export _scl_root="/opt/cpanel//root"
export _sysconfdir="/opt/cpanel//root/etc"
export _unitdir="/usr/lib/systemd/system"
export ai_advisor_version="1.91"
export buildroot="/usr/src/packages/BUILD"
export full_package_name="cpanel-ai-advisor-1.91"
export ix86="i386"
export name="cpanel-ai-advisor"
export nil="0"
export ns_name="ea"
export pkg=""
export pkg_name=""
export pkgname=""
export previous_version="1.90"
export release="1"
export release_prefix="1"
export scl=""
export scl_name=""
export scl_name_base=""
export scl_name_version=""
export scl_prefix=""
export version="1.91"
export version_with_debian_revision="1.91-1"
export SOURCE1="$DEB_SOURCE_ROOT/pkg.preinst"
export SOURCE2="$DEB_SOURCE_ROOT/pkg.postinst"
export SOURCE3="$DEB_SOURCE_ROOT/pkg.prerm"
export SOURCE4="$DEB_SOURCE_ROOT/pkg.postrm"
# End vars.sh

# summary of how this script can be called:
#        * <postinst> `configure' <most-recently-configured-version>
#        * <old-postinst> `abort-upgrade' <new version>
#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
#          <new-version>
#        * <postinst> `abort-remove'
#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
#          <failed-install-package> <version> `removing'
#          <conflicting-package> <version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package


case "$1" in
    configure)
    ;;

    abort-upgrade|abort-remove|abort-deconfigure)
    ;;

    *)
        echo "postinst called with unknown argument \`$1'" >&2
        exit 1
    ;;
esac

# Contents of SOURCES/pkg.postinst
#!/bin/bash

# PRIOR-INSTALL DETECTION - MUST BE THE FIRST THING THIS SCRIPT DOES.
#
# The feature-list seeding further down needs to know whether an earlier build of
# this package has ever been installed (CPANEL-55247). It cannot ask rpm, because
# this postinst is shared with the deb build where $1 differs, and it cannot ask
# the feature list, because in that file an ABSENT feature means ENABLED - so
# "not there" and "the admin turned it on" are the same state.
#
# So it asks the filesystem for evidence a previous postinst ran. That evidence
# has to be sampled HERE, above every mkdir and every create-if-missing block
# below, because this run is about to create most of it. Moving this block down
# silently converts every upgrade into a first install, which is the bug.
#
# Several independent signals, deliberately:
#   - the seeding sentinel, when a build that had it ran;
#   - gateway.json and telemetry_salt, both create-if-missing by this script and
#     therefore present on any server it has ever configured (gateway.json
#     predates the component-era build below, which is what makes it the reliable
#     one);
#   - either addonfeature descriptor.
#
# The descriptors ALONE are not enough, and this is the case that made the list
# necessary: commit 0e8085f (CPANEL-54524) registered the features through an
# optional-component driver instead, dropped both descriptor files, and shipped a
# migration that DELETED the installed ones. A server from that era has its Act
# tier enabled, no descriptor, and no feature-list line - so a descriptor-only
# check reads it as a first install and re-seeds ai-assistant-actions=0, which is
# precisely the regression this change exists to end.
#
# -e rather than -f throughout: an unusable node (a directory where a file was
# expected) still counts as evidence, so a damaged marker cannot downgrade an
# upgrade into a re-seed.
AI_PRIOR_INSTALL=0
for _ai_evidence in \
    /var/cpanel/ai/.featurelist_seeded \
    /var/cpanel/ai/gateway.json \
    /var/cpanel/ai/telemetry_salt \
    /usr/local/cpanel/whostmgr/addonfeatures/ai-assistant \
    /usr/local/cpanel/whostmgr/addonfeatures/ai-assistant-actions; do
    if [ -e "$_ai_evidence" ]; then
        AI_PRIOR_INSTALL=1
        break
    fi
done
unset _ai_evidence

# Remove the retired root-owned audit store (CPANEL-55315). Records live in each
# account's own home now. The ones left here are unreachable by the account they
# describe - it cannot read them and cannot delete them - and every one carries the
# unkeyed whole-args digest this design stopped persisting, from which a mailbox
# password was recovered in six dictionary guesses. There is nothing to migrate: the
# account-owned store is authoritative, and these cannot be moved into it without
# re-introducing exactly the field they were dropped for.
if [ -d /var/cpanel/ai/audit ]; then
    rm -rf /var/cpanel/ai/audit
fi

# Create runtime directories.
mkdir -p /var/cpanel/ai/cache /var/cpanel/ai/proposals

# 0711 (traverse, not list): unprivileged cPanel users must open the 0644
# gateway.json directly (Cpanel::AI::Config::load reads it in-process during UAPI
# dispatch, no AdminBin) without being able to enumerate the dir, keeping the
# 0600 telemetry_salt unlistable. The RPM also owns this mode via
# %dir %attr, but the deb build's dh_fixperms normalizes dirs to 0755 — so assert
# it here to keep RPM and deb consistent at 0711.
chmod 0711 /var/cpanel/ai

# ---------------------------------------------------------------------------
# Gateway configuration — create default if missing
# ---------------------------------------------------------------------------
GATEWAY_JSON="/var/cpanel/ai/gateway.json"

if [ ! -f "$GATEWAY_JSON" ]; then
    # Single gateway endpoint (assistant_url) -> the semantic-search-gate proxy,
    # which validates the WebPros OIDC JWT we send. The OAuth base URI is not
    # configured here: it comes from the core provider's default or
    # /var/cpanel/webpros_oidc_overrides (staging); the auth_server key is
    # retired and not read (CPANEL-55205).
    cat > "$GATEWAY_JSON" <<'JSON'
{
    "assistant_url": "https://semantic-search.plesk.com",
    "tls_verify": true
}
JSON
    chmod 0644 "$GATEWAY_JSON"
fi

# Telemetry salt (EP-CPAI-05 Story 5.7): a root-only 0600 secret, minted once at
# install. Only root - via the ai_assistant
# AdminBin - reads it to derive CP_AI_* identity digests; the salt never enters an
# account process, so telemetry is safe on by default (sends stay consent-gated).
# No salt -> the emitter fails closed (off). It does not touch gateway.json; a
# legacy 5.1 hand-set distinct_id_salt there is unused by 5.7 and should be
# removed by hand.
TELEMETRY_SALT="/var/cpanel/ai/telemetry_salt"

# An existing salt must be a root-only 0600 file whose content is the canonical
# mint format (exactly 64 lowercase hex, no trailing newline). Mode drift (config
# management, a restore without -p) can expose the secret, and a weak/short value
# (e.g. a config-managed placeholder) yields brute-forceable HMACs - on either
# deviation, discard and re-mint rather than trust it (distinct_id rotation is
# acceptable for telemetry). The perl format check mirrors _read_salt exactly.
if [ -f "$TELEMETRY_SALT" ] && { [ "$(stat -c '%a %u' "$TELEMETRY_SALT" 2>/dev/null)" != "600 0" ] || \
     ! /usr/local/cpanel/3rdparty/bin/perl -e '
         open my $f, "<:raw", $ARGV[0] or exit 1;
         my $s = do { local $/; <$f> };
         exit( ( defined $s && $s =~ /\A[0-9a-f]{64}\z/ ) ? 0 : 1 );
     ' "$TELEMETRY_SALT"; }; then
    rm -f "$TELEMETRY_SALT"
    echo "cpanel-ai-advisor postinst: WARNING: telemetry salt was not a root-only 0600 64-hex secret - discarded, re-minting a fresh one." >&2
fi

if [ ! -f "$TELEMETRY_SALT" ]; then
    # Partial-write cleanup lives INSIDE the perl (unlink only after our own O_EXCL
    # create) so a concurrent create's EEXIST can never delete a salt this process
    # did not make.
    if /usr/local/cpanel/3rdparty/bin/perl -MFcntl=:DEFAULT -e '
        open my $u, "<:raw", "/dev/urandom" or die "urandom: $!";
        read( $u, my $b, 32 ) == 32 or die "short read";
        sysopen my $f, $ARGV[0], O_WRONLY | O_CREAT | O_EXCL, 0600 or die "create: $!";
        eval {
            print {$f} unpack( "H*", $b ) or die "write: $!";
            close $f or die "close: $!";
            1;
        } or do { unlink $ARGV[0]; die $@ };
    ' "$TELEMETRY_SALT"; then
        echo "cpanel-ai-advisor postinst: CP_AI_* telemetry salt minted (root-only 0600); telemetry on by default, still gated by user analytics consent (docs/DATA-PRIVACY.md section 3)." >&2
    else
        echo "cpanel-ai-advisor postinst: WARNING: telemetry salt minting failed - telemetry stays OFF (fail closed)." >&2
    fi
fi

# ---------------------------------------------------------------------------
# Symlink UAPI / SSE modules into cPanel's @INC path
# ---------------------------------------------------------------------------
# UAPI and SSE modules are resolved via Cpanel::LoadModule, which searches the
# ULC tree (/usr/local/cpanel) only, NOT /var/cpanel/perl. Symlink ours in so
# cpsrvd can find them.
ULC="/usr/local/cpanel"

# AIAssistant UAPI module (cPanel Meridian hub: AIAssistant::ask / ::status)
UAPI_AISRC="/var/cpanel/perl/Cpanel/API/AIAssistant.pm"
UAPI_AIDST="$ULC/Cpanel/API/AIAssistant.pm"

if [ -f "$UAPI_AISRC" ] && [ ! -e "$UAPI_AIDST" ]; then
    ln -sf "$UAPI_AISRC" "$UAPI_AIDST"
fi

# AIAssistant AdminBin module (privileged gateway.json read; shipped for
# AdminBin discovery — the v1 UAPI path uses the transport directly).
ADMIN_AISRC="/var/cpanel/perl/Cpanel/Admin/Modules/Cpanel/ai_assistant.pm"
ADMIN_AIDST="$ULC/Cpanel/Admin/Modules/Cpanel/ai_assistant.pm"

if [ -f "$ADMIN_AISRC" ] && [ ! -e "$ADMIN_AIDST" ]; then
    mkdir -p "$ULC/Cpanel/Admin/Modules/Cpanel"
    ln -sf "$ADMIN_AISRC" "$ADMIN_AIDST"
fi

# AIAssistant streaming SSE endpoint (cPanel Meridian: ./sse/AIAssistant).
# cpsrvd resolves SSE modules via Cpanel::LoadModule, which searches the ULC tree
# only (NOT /var/cpanel/perl), so symlink ours in - same pattern as the UAPI
# module above. NOTE: streaming also needs core cpsrvd support for delivering a
# POST body to SSE modules (Cpanel::Server::SSE::_get_request_body); that ships
# with cpanel core, not this package.
SSE_AISRC="/var/cpanel/perl/Cpanel/Server/SSE/cpanel/AIAssistant.pm"
SSE_AIDST="$ULC/Cpanel/Server/SSE/cpanel/AIAssistant.pm"

if [ -f "$SSE_AISRC" ] && [ ! -e "$SSE_AIDST" ]; then
    mkdir -p "$ULC/Cpanel/Server/SSE/cpanel"
    ln -sf "$SSE_AISRC" "$SSE_AIDST"
fi

# ---------------------------------------------------------------------------
# Symlink the per-function OpenAPI specs into the ULC Cpanel/API tree
# ---------------------------------------------------------------------------
# The specs ship to /var/cpanel/perl/Cpanel/API/ beside the module, but every
# consumer looks for them next to the module cPanel itself resolves - that is, in
# the ULC tree, at $ULC/Cpanel/API/<Module>-<function>.openapi.yaml:
#
#   - core's t/large/verify_api_documentation.t enumerates UAPI functions from
#     Cpanel::ApiInfo::UAPI and -f tests exactly that path. It does NOT skip our
#     module: its skip is "owned by an RPM", asked of $ULC/Cpanel/API/AIAssistant.pm,
#     and that is a symlink THIS script makes, which no package owns. So without the
#     link every one of our functions reads as undocumented, and the failure lands on
#     the whole cpanel-whm branch rather than on us - every PR against 138 and 140
#     went red on it (CPANEL-56217).
#   - Cpanel::AIAssistant::Corpus globs the same directory for its discovery index.
#
# Shipping the specs to /var/cpanel/perl and never linking them meant they existed
# on the box and were visible to nobody. Glob rather than list the four names, so a
# spec added for a new function is carried across by the same code that ships it.
API_SPEC_SRCDIR="/var/cpanel/perl/Cpanel/API"
API_SPEC_DSTDIR="$ULC/Cpanel/API"

mkdir -p "$API_SPEC_DSTDIR"

# Prune first: a spec an earlier build linked and we no longer ship (a renamed or
# retired function) leaves a DANGLING link behind, and a dangling link fails the -f
# test exactly like a missing file while looking installed. Only links pointing into
# our own source dir are considered - never a real file, never someone else's link.
for _stale_link in "$API_SPEC_DSTDIR"/AIAssistant-*.openapi.yaml; do
    [ -L "$_stale_link" ] || continue
    case "$(readlink "$_stale_link")" in
        "$API_SPEC_SRCDIR"/*) [ -e "$_stale_link" ] || rm -f "$_stale_link" ;;
    esac
done
unset _stale_link

for _spec in "$API_SPEC_SRCDIR"/AIAssistant-*.openapi.yaml; do
    [ -f "$_spec" ] || continue    # an unmatched glob stays literal
    _spec_dst="$API_SPEC_DSTDIR/$( basename "$_spec" )"
    [ -e "$_spec_dst" ] && continue    # create-if-absent, as for the modules above
    ln -sf "$_spec" "$_spec_dst"
done
unset _spec _spec_dst

# ---------------------------------------------------------------------------
# Register cPanel features (Feature Manager) — addonfeatures
# ---------------------------------------------------------------------------
# ai-assistant        : read tier. Gates the whole assistant + read actions.
# ai-assistant-actions: Act tier. Gates write actions.
#
# These MUST be registered as static addonfeatures descriptors: the Feature
# Manager edit path (WHMAPI update_featurelist) only accepts feature names it
# finds via load_feature_names()/load_addon_feature_names() — i.e. these files.
# A ConfigObj optional-component driver alone does NOT make the names valid for
# update_featurelist (it only feeds the create_featurelist/save path), so a
# component-only registration made both checkboxes silently un-saveable
# (CPANEL-54524 regressed this; the provider kill switch now lives entirely in
# Cpanel::AI::Config + the API layer, independent of Feature Manager visibility).
ADDON_DIR="/usr/local/cpanel/whostmgr/addonfeatures"
DEFAULT_FEATURES="/var/cpanel/features/default"

# Marks that first-install seeding has already happened. See the seeding block
# below for why the feature list itself cannot answer that question.
FEATURELIST_SEEDED="/var/cpanel/ai/.featurelist_seeded"

mkdir -p "$ADDON_DIR"

# THE FEATURE LIST IS A DISABLED-LIST, NOT A SETTINGS TABLE (CPANEL-55247).
#
# /var/cpanel/features/default records only features that are OFF. A feature
# ABSENT from that file is ENABLED. So "no line for this token" and "the admin
# turned this token on" are the SAME STATE, and a presence check cannot tell
# them apart.
#
# This function used to seed its default whenever the token was absent, which
# meant every upgrade re-appended ai-assistant-actions=0 and silently switched
# off an Act tier the admin had deliberately enabled. Observed four times in one
# evening on a single box. The read tier escaped only by luck: it seeds =1, and
# writing =1 into a file that stores only zeroes is a no-op.
#
# So seeding is a FIRST-INSTALL action and an upgrade writes nothing at all.
# "First install" is decided by AI_PRIOR_INSTALL, sampled at the very top of this
# script - see the long comment there for why the evidence has to be collected
# before anything else runs, and why the descriptor alone is not enough.
if [ "$AI_PRIOR_INSTALL" = "1" ] && [ ! -e "$FEATURELIST_SEEDED" ]; then

    # An earlier build is installed but predates the sentinel. Claim it WITHOUT
    # seeding: without this, every server already carrying the plugin loses the
    # setting one last time on the very upgrade that fixes the bug.
    touch "$FEATURELIST_SEEDED" 2>/dev/null || true
fi

register_feature() {
    local token="$1"
    local default="$2"    # default feature-list value (1=on, 0=off)
    local src="/var/cpanel/ai/addonfeatures_${token}"
    local dst="$ADDON_DIR/${token}"

    # The descriptor copy is UNCONDITIONAL and stays above the seeding return:
    # it is what makes the checkbox visible and saveable in Feature Manager, and
    # that must never depend on feature-list seeding (CPANEL-54524 is the
    # regression where a registration change made both checkboxes un-saveable).
    if [ -f "$src" ] && [ ! -f "$dst" ]; then
        cp "$src" "$dst"
        chmod 0644 "$dst"
    fi

    # Anything but a genuine first install leaves the admin's configuration
    # alone, in either direction. Writing nothing is also what keeps an
    # explicitly DISABLED tier disabled - "stop forcing it off" must not become
    # "force it on".
    #
    # Both conditions are checked, not just the sentinel: if the sentinel is
    # unwritable or was created as a directory, `touch` above fails and -e can
    # still be false, and relying on it alone would re-seed on every upgrade
    # forever. AI_PRIOR_INSTALL does not depend on this file being writable.
    [ "$AI_PRIOR_INSTALL" = "1" ] && return 0
    [ -e "$FEATURELIST_SEEDED" ] && return 0

    # First install only. The Act tier is written explicitly =0 so it is
    # present-and-off (an admin can flip it on in Feature Manager); runtime write
    # capability is separately gated by the fail-closed provider switch
    # ai.enable_assistant_actions (Cpanel::AI::Config).
    #
    # The append CREATES the file when it is absent, deliberately. Absent means
    # every feature is enabled, so skipping the write on a server with no default
    # feature list would ship the Act tier ON - the opposite of the intended
    # default, and unrecoverable afterwards because the next run is no longer a
    # first install. A file containing only this line still leaves every other
    # feature enabled, so creating it changes nothing else.
    if ! grep -q "^${token}=" "$DEFAULT_FEATURES" 2>/dev/null; then
        echo "${token}=${default}" >> "$DEFAULT_FEATURES"
        chmod 0644 "$DEFAULT_FEATURES" 2>/dev/null || true
    fi
}

register_feature "ai-assistant"         1
register_feature "ai-assistant-actions" 0

# Claim the sentinel AFTER both calls, so a first install seeds both tokens and
# every later run seeds neither. Failure to write it is not fatal:
# AI_PRIOR_INSTALL will recognise this server on the next upgrade regardless.
touch "$FEATURELIST_SEEDED" 2>/dev/null || true

# Migration (idempotent): CPANEL-54524 briefly registered the assistant as a
# Cpanel::Component (config.json + ULC ConfigObj driver/META + Config.pm
# symlinks) INSTEAD of these addonfeatures, which made both checkboxes
# un-saveable via Feature Manager. Undo that registration on upgrade so no
# phantom component / dangling symlink is left pointing at the removed driver.
rm -f "$ULC/Cpanel/Config/ConfigObj/Driver/AiAssistant.pm"
rm -f "$ULC/Cpanel/Config/ConfigObj/Driver/AiAssistant/META.pm"
rmdir "$ULC/Cpanel/Config/ConfigObj/Driver/AiAssistant" 2>/dev/null || true
if [ -L "$ULC/Cpanel/AI/Config.pm" ]; then
    rm -f "$ULC/Cpanel/AI/Config.pm"
fi
PLUGINS_CONF="/var/cpanel/plugins/config.json"
if [ -s "$PLUGINS_CONF" ]; then
    /usr/local/cpanel/3rdparty/bin/perl -MCpanel::JSON -e '
        my $f = shift;
        my $d = eval { Cpanel::JSON::LoadFile($f) };    # leave untouched on parse failure
        if ( ref $d eq q{HASH} && exists $d->{q{ai-assistant}} ) {
            delete $d->{q{ai-assistant}};
            Cpanel::JSON::DumpFile( $f, $d );
        }
    ' "$PLUGINS_CONF" 2>/dev/null || true
fi

# ---------------------------------------------------------------------------
# Migration (idempotent): drop the retired AI Advisor frontend injections.
# ---------------------------------------------------------------------------
# Builds before 1.20 appended an AI_ADVISOR_PLUGIN marker block to the cPanel
# Jupiter content include and the WHM global banner. Those blocks load
# ai-advisor.css / ai-advisor.js from a frontend bundle this package no longer
# ships: that prototype UI was retired, and the surface we ship now is the
# Meridian hub, which loads its own assets. The matching cleanup used to live in
# pkg.prerm, which only runs on a full package removal - never on upgrade. So
# every server that ever carried a pre-1.20 build keeps emitting <link> and
# <script> tags for files that are gone, and each page load 404s twice.
#
# Strip only our own marker block, and only when the markers form a clean
# sequence of closed pairs. Checking that both markers merely EXIST is not
# enough: `/START/,/END/d` resolves the range end by scanning forward from the
# line after START, so any malformed layout can run the range past our block
# and delete unrelated customizations.
#
#   END before START  - the range opens at START, finds no END after it, and
#                       deletes to EOF.
#   START with no END - same runaway to EOF (the original guard's case).
#   START START ... END - the range closes at the first END and strands the
#                       second START, leaving a marker behind.
#   both on one line  - the end address is searched from the NEXT line, so the
#                       range runs on to the next END or EOF.
#
# A hand-edited or truncated file can be in any of these states, and this runs
# as root against files that may hold customizations this package does not own.
# Over-deleting is far worse than leaving a stale block behind, so on anything
# that is not well formed we touch nothing and say so loudly enough to be found
# in the update log. The include file itself is left in place even if it ends up
# empty - an empty include is inert.
_ai_advisor_markers_well_formed() {
    awk '
        /AI_ADVISOR_PLUGIN_START/ && /AI_ADVISOR_PLUGIN_END/ { bad = 1; exit }
        /AI_ADVISOR_PLUGIN_START/ { if (open) { bad = 1; exit } open = 1; seen = 1; next }
        /AI_ADVISOR_PLUGIN_END/   { if (!open) { bad = 1; exit } open = 0; next }
        END { exit( ( bad || !seen || open ) ? 1 : 0 ) }
    ' "$1" 2>/dev/null
}

for _stale_include in \
    /var/cpanel/customizations/content_includes/cpanel_jupiter_header_after.html.tt \
    /var/cpanel/customizations/whm/includes/global_banner.html.tt
do
    [ -f "$_stale_include" ] || continue
    grep -q 'AI_ADVISOR_PLUGIN' "$_stale_include" 2>/dev/null || continue

    if ! _ai_advisor_markers_well_formed "$_stale_include"; then
        echo "cpanel-ai-advisor postinst: WARNING: the AI_ADVISOR_PLUGIN markers in $_stale_include are malformed or out of order - leaving the file untouched. Remove the stale block by hand; deleting the marker range automatically could take unrelated customizations with it." >&2
        continue
    fi

    sed -i '/AI_ADVISOR_PLUGIN_START/,/AI_ADVISOR_PLUGIN_END/d' "$_stale_include"
    echo "cpanel-ai-advisor postinst: removed the retired AI Advisor asset injection from $_stale_include" >&2
done

# ---------------------------------------------------------------------------
# Reload cpsrvd so the freshly-installed/updated modules take effect.
# ---------------------------------------------------------------------------
# cpsrvd preloads our UAPI/SSE modules; a running daemon keeps serving the
# previously-loaded code until it is restarted. Without this, a fresh install or
# upgrade appears to "do nothing different" until the next unrelated cpsrvd
# restart. A graceful restart picks up the new code immediately.
if [ -x /usr/local/cpanel/scripts/restartsrv_cpsrvd ]; then
    /usr/local/cpanel/scripts/restartsrv_cpsrvd >/dev/null 2>&1 || true
fi

echo "AI Advisor plugin installed successfully"
# End SOURCES/pkg.postinst


exit 0
