#!/usr/bin/env bash

# The Sharing page must report what is true, and never claim a security
# property it cannot back up.
#
# The two failures worth a test:
#
#   A service that is not installed shown as a switch. That is what the panel
#   this replaces does, and the switch does nothing.
#
#   "Keys only" claimed for SSH when the configuration is silent. OpenSSH's
#   default accepts passwords, so stating the stronger thing without evidence
#   would tell someone their machine is safer than it is.
#
# Read-only: this reads service state and never enables or disables anything.

set -uo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
helper="$repo_dir/config/dot/quickshell/scripts/panama-sharing"
service="$repo_dir/config/dot/quickshell/services/Sharing.qml"
page="$repo_dir/config/dot/quickshell/modules/settings/SharingPage.qml"

fail() {
    printf 'sharing contract: %s\n' "$1" >&2
    exit 1
}

for path in "$helper" "$service" "$page"; do
    [[ -r "$path" ]] || fail "missing $path"
done
[[ -x "$helper" ]] || fail 'panama-sharing is not executable'

# ── The password-authentication claim is evidence-based ─────────────────────
summary="$(sed -n '/function passwordLoginSummary/,/^    }/p' "$service")"
[[ -n "$summary" ]] || fail 'the service does not summarize password sign-in'
grep -q 'stated === ""' <<<"$summary" \
    || fail 'the summary does not distinguish "configured" from "silent"'
grep -qE 'system default' <<<"$summary" \
    || fail 'a silent configuration is not reported as the system default'
# "Keys only" may only be said when the file actually says no.
keys_line="$(grep -n 'keys only' <<<"$summary" | head -1)"
[[ -n "$keys_line" ]] || fail 'the summary never reports keys-only'
grep -q 'toLowerCase() === "no"' <<<"$summary" \
    || fail 'keys-only is claimed without checking what the configuration says'

# ── Absent software is reported, not offered ────────────────────────────────
grep -q 'is not installed' "$page" \
    || fail 'the page does not say when the software for a row is missing'
# A switch for a service that is not installed must be disabled.
grep -q 'Sharing.remoteLogin?.installed === true' "$page" \
    || fail 'the remote login switch is enabled regardless of whether SSH is installed'
grep -q 'Sharing.remoteDesktop?.available === true' "$page" \
    || fail 'the remote desktop switch is enabled regardless of whether it is available'

# Turning on remote desktop without credentials would start a service nobody
# can connect to; the page must require them first.
grep -q 'hasCredentials === true' "$page" \
    || fail 'remote desktop can be enabled with no credentials set'
grep -q 'hasCredentials' "$helper" \
    || fail 'the helper does not know whether credentials exist'
grep -qiE 'grdctl.*(password|username)[^)]*\)' "$helper" \
    && fail 'the helper passes remote desktop credentials on a command line'

# ── Privilege boundaries ────────────────────────────────────────────────────
# Remote login is system-wide and must go through a prompt; remote desktop is a
# user service and must not ask for one.
login_body="$(sed -n '/^def set_remote_login/,/^def /p' "$helper")"
grep -q 'pkexec' <<<"$login_body" \
    || fail 'changing a system-wide service does not ask for authorization'
desktop_body="$(sed -n '/^def set_remote_desktop/,/^def /p' "$helper")"
grep -q 'pkexec' <<<"$desktop_body" \
    && fail 'a user service asks for administrator rights it does not need'
grep -q '"--user"' <<<"$desktop_body" \
    || fail 'remote desktop is not managed as a user service'

# ── The remote desktop password never passes through Panama ────────────────
# grdctl takes it on a terminal and core-dumps without one, so the only two
# options were a terminal hand-off or an argument -- and an argument publishes
# it through /proc to every process on this machine.
grep -q 'set-credentials' "$service" \
    || fail 'the service cannot set remote desktop credentials at all'
grep -qE 'set-credentials".*(password|secret)' "$service" \
    && fail 'the service puts a password on the command line'
grep -q 'set-credentials' "$helper" \
    && fail 'the helper handles credentials; that path cannot prompt and must stay in a terminal'
grep -q 'kitty' "$service" \
    || fail 'credentials are not handed to a terminal, so nothing can prompt for them'
grep -q 'clear-rdp-credentials' "$helper" \
    || fail 'stored credentials cannot be cleared'

# ── The snapshot reflects the machine ───────────────────────────────────────
command -v jq >/dev/null 2>&1 || { printf 'sharing contract: SKIP (no jq)\n'; exit 0; }
snapshot="$("$helper" snapshot 2>/dev/null)" || fail 'snapshot failed'
jq -e '.hostname | length > 0' <<<"$snapshot" >/dev/null || fail 'no hostname reported'
jq -e '.remoteLogin | has("installed") and has("active") and has("enabled")' <<<"$snapshot" >/dev/null \
    || fail 'remote login state is incomplete'
jq -e '.remoteDesktop | has("available") and has("hasCredentials")' <<<"$snapshot" >/dev/null \
    || fail 'remote desktop state is incomplete'

# Installed-ness must match what is actually on this machine, not a guess.
expected_samba=$(command -v smbd >/dev/null 2>&1 && echo true || echo false)
actual_samba="$(jq -r '.fileSharing.installed' <<<"$snapshot")"
[[ "$expected_samba" == "$actual_samba" ]] \
    || fail "file sharing reports installed=$actual_samba but smbd presence is $expected_samba"

# No credential may appear in the snapshot.
offenders="$(jq -r '[paths | map(tostring) | join(".")] | map(select(test("(password|secret|credential)$";"i"))) | join(", ")' <<<"$snapshot")"
[[ -z "$offenders" ]] || fail "the snapshot carries credential-shaped fields: $offenders"

printf 'sharing contract: PASS (remote login %s, remote desktop %s)\n' \
    "$(jq -r 'if .remoteLogin.active then "on" else "off" end' <<<"$snapshot")" \
    "$(jq -r 'if .remoteDesktop.active then "on" else "off" end' <<<"$snapshot")"
