#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2026 Marco Allegretti <mightymarco4@gmail.com>
# SPDX-License-Identifier: GPL-2.0-or-later

set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

constants="$repo_root/components/mobileshell/qml/components/Constants.qml"
panel="$repo_root/containments/panel/qml/main.qml"
taskpanel="$repo_root/containments/taskpanel/qml/main.qml"
folio_main="$repo_root/containments/homescreens/folio/qml/main.qml"
folio_home="$repo_root/containments/homescreens/folio/qml/FolioHomeScreen.qml"
folio_backend="$repo_root/containments/homescreens/folio/homescreen.h"
folio_backend_cpp="$repo_root/containments/homescreens/folio/homescreen.cpp"
action_content="$repo_root/components/mobileshell/qml/actiondrawer/private/ContentContainer.qml"
action_landscape="$repo_root/components/mobileshell/qml/actiondrawer/private/LandscapeContentContainer.qml"
quick_settings="$repo_root/components/mobileshell/qml/actiondrawer/private/QuickSettings.qml"
quick_settings_panel="$repo_root/components/mobileshell/qml/actiondrawer/private/QuickSettingsPanel.qml"

require_line() {
    local file="$1"
    local needle="$2"

    if ! grep -Fq -- "$needle" "$file"; then
        echo "Missing invariant in ${file#$repo_root/}: $needle" >&2
        exit 1
    fi
}

require_line "$constants" "readonly property real convergenceDockHeight: Kirigami.Units.gridUnit * 3"
require_line "$constants" "readonly property real convergenceDockRevealHeight: Kirigami.Units.gridUnit"
require_line "$constants" "readonly property real convergenceWorkspaceFrameThickness:"
require_line "$constants" "readonly property real convergenceWorkspaceFrameRadius:"

require_line "$panel" "readonly property real convergenceWorkspaceFrameThickness:"
require_line "$panel" "height: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)"
require_line "$panel" "LayerShell.Window.exclusionZone: Math.max(1, root.panelHeight + root.convergenceWorkspaceFrameThickness)"

require_line "$taskpanel" "readonly property real convergenceWorkspaceFrameThickness:"
require_line "$taskpanel" "height: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness"
require_line "$taskpanel" "LayerShell.Window.exclusionZone: MobileShell.Constants.convergenceDockHeight + root.convergenceWorkspaceFrameThickness"
require_line "$taskpanel" "LayerShell.Window.scope: \"workspace-frame-left\""
require_line "$taskpanel" "LayerShell.Window.scope: \"workspace-frame-right\""

require_line "$folio_main" "height: MobileShell.Constants.convergenceDockHeight"
require_line "$folio_main" "readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight"
require_line "$folio_main" "readonly property real revealStripHeight: MobileShell.Constants.convergenceDockRevealHeight"
require_line "$folio_main" "import QtQuick.Shapes 1.8"
require_line "$folio_main" "id: workspaceFrame"
require_line "$folio_main" "readonly property real frameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness"
require_line "$folio_main" "readonly property real frameRadius:"
require_line "$folio_main" "readonly property real workAreaX: frameThickness"
require_line "$folio_main" "readonly property real workAreaY: topReservedHeight + frameThickness"
require_line "$folio_main" "readonly property real workAreaWidth: Math.max(0, width - frameThickness * 2)"
require_line "$folio_main" "readonly property real workAreaHeight: Math.max(0, height - topReservedHeight - bottomReservedHeight - frameThickness * 2)"
require_line "$folio_main" "fillRule: ShapePath.OddEvenFill"
require_line "$folio_main" "PathLine { x: workspaceFrame.width; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }"
require_line "$folio_main" "PathLine { x: 0; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }"
require_line "$folio_main" "PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }"
require_line "$folio_main" "PathArc { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }"
require_line "$folio_main" "readonly property real popupTopY: MobileShell.Constants.topPanelHeight"
require_line "$folio_main" "+ MobileShell.Constants.convergenceWorkspaceFrameThickness"
require_line "$folio_main" "readonly property real popupBottomY: parent.height"
require_line "$folio_main" "- MobileShell.Constants.convergenceWorkspaceFrameThickness"
require_line "$folio_main" "readonly property real popupHeight: Math.max(0, popupBottomY - popupTopY)"
require_line "$folio_main" "? popupTopY + animationY"
require_line "$folio_home" "height: ShellSettings.Settings.convergenceModeEnabled ? MobileShell.Constants.convergenceDockHeight : Kirigami.Units.gridUnit * 6"
require_line "$folio_home" "&& !ShellSettings.Settings.convergenceModeEnabled"
require_line "$folio_backend" "Q_PROPERTY(bool overviewActive READ overviewActive NOTIFY overviewActiveChanged)"

overview_hide_guards="$(grep -F "&& !folio.overviewActive" "$folio_main" | wc -l)"
if [[ "$overview_hide_guards" -ne 2 ]]; then
    echo "Expected the Folio convergence workspace frame and dock overlay to hide during KWin Overview; found $overview_hide_guards overview guards" >&2
    exit 1
fi

if ! awk '
    /void HomeScreen::triggerOverview\(\)/ { in_trigger = 1; next }
    in_trigger && /setOverviewActive\(true\);/ { saw_pre_hide = 1; next }
    in_trigger && /createMethodCall/ {
        if (saw_pre_hide) {
            found = 1
            exit 0
        }
        exit 1
    }
    in_trigger && /^}/ { exit 1 }
    END { if (!found) exit 1 }
' "$folio_backend_cpp"; then
    echo "Expected Folio to hide convergence chrome before invoking KWin Overview" >&2
    exit 1
fi

require_line "$action_content" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight"
require_line "$action_content" "readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness"
require_line "$action_content" "readonly property real convergenceSurfaceSideInset: 0"
require_line "$action_content" "topMargin: isConvergence ? root.convergenceSurfaceTopInset : 0"
require_line "$action_content" "leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : (isConvergence ? root.convergenceSurfaceSideInset"
require_line "$action_content" "maximumHeight: isConvergence ? root.convergenceSurfaceHeight * 0.6 : -1"

require_line "$action_landscape" "readonly property real convergenceSurfaceTopInset: MobileShell.Constants.topPanelHeight"
require_line "$action_landscape" "readonly property real convergenceSurfaceBottomInset: MobileShell.Constants.convergenceDockHeight + convergenceFrameThickness"
require_line "$action_landscape" "readonly property real convergenceSurfaceSideInset: 0"
require_line "$action_landscape" "anchors.topMargin: isConvergence ? restingTopMargin"
require_line "$action_landscape" "anchors.rightMargin: isConvergence ? root.convergenceSurfaceSideInset : 0"
require_line "$action_landscape" "fullScreenHeight: quickSettingsPanel.availableHeight"

require_line "$quick_settings_panel" "readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled"
require_line "$quick_settings_panel" "readonly property real panelPadding: isConvergence ? Kirigami.Units.smallSpacing : Kirigami.Units.smallSpacing * 4"
require_line "$quick_settings_panel" "anchors.margins: root.isConvergence ? 0 : Kirigami.Units.largeSpacing"
require_line "$quick_settings_panel" "panelType: root.isConvergence ? MobileShell.PanelBackground.PanelType.Flat : MobileShell.PanelBackground.PanelType.Base"
require_line "$quick_settings_panel" "radius: root.isConvergence ? 0 : Kirigami.Units.cornerRadius"

require_line "$quick_settings" "id: convergenceFlow"
require_line "$quick_settings" "visible: root.isConvergence"
require_line "$quick_settings" "visible: !root.isConvergence"
require_line "$quick_settings" "active: !root.isConvergence && swipeView.count > 1 ? true: false"

frame_arc_count="$(grep -F "PathArc {" "$folio_main" | wc -l)"
if [[ "$frame_arc_count" -ne 4 ]]; then
    echo "Expected the workspace frame cutout to have four rounded inner corners; found $frame_arc_count arcs" >&2
    exit 1
fi

if grep -Fq "convergenceWallpaperLayer" "$folio_main"; then
    echo "Do not replace the real wallpaper with a custom convergence wallpaper layer" >&2
    exit 1
fi

dock_offset_transforms="$(grep -F "transform: Translate { y: dockOverlay.dockOffset }" "$folio_main" | wc -l)"
if [[ "$dock_offset_transforms" -ne 1 ]]; then
    echo "Expected only dock contents to slide with dockOverlay.dockOffset; found $dock_offset_transforms transforms" >&2
    exit 1
fi
