#!/usr/bin/env bash

# Device security facts, as JSON.
#
# Everything here is READ-ONLY and deliberately so. Secure Boot, TPM presence,
# disk encryption, SELinux mode and the firewall are set in firmware, at install
# time, or by system policy -- none of them is a desktop preference, and a
# settings app that offered to toggle them would either fail or do something
# far-reaching from a switch that looks like any other.
#
# What it is for is answering "is this machine set up the way I think it is",
# which is the question GNOME's Device Security panel exists to answer and which
# otherwise needs five commands and root.
#
# Each fact is reported as {value, ok} where `ok` marks the reassuring state, so
# the UI can highlight what deserves attention without hard-coding the meaning
# of each string. Anything that cannot be determined reports "Unknown" with
# ok:false rather than guessing, because a security readout that quietly reports
# "fine" when it failed to look is worse than no readout.

set -uo pipefail

fact() {
    jq -cn --arg label "$1" --arg value "$2" --argjson ok "$3" --arg detail "${4:-}" \
        '{label: $label, value: $value, ok: $ok, detail: $detail}'
}

facts=()

# ── Secure Boot ──────────────────────────────────────────────────────────────
if command -v mokutil >/dev/null 2>&1; then
    case "$(mokutil --sb-state 2>/dev/null)" in
        *"SecureBoot enabled"*)  facts+=("$(fact "Secure Boot" "Enabled" true "Firmware verifies the bootloader and kernel signatures")" ) ;;
        *"SecureBoot disabled"*) facts+=("$(fact "Secure Boot" "Disabled" false "Firmware does not verify what it boots")") ;;
        *)                       facts+=("$(fact "Secure Boot" "Unknown" false "The firmware did not report a Secure Boot state")") ;;
    esac
elif [[ -d /sys/firmware/efi ]]; then
    facts+=("$(fact "Secure Boot" "Unknown" false "Install mokutil to report this")")
else
    facts+=("$(fact "Secure Boot" "Not applicable" false "This machine booted in legacy BIOS mode")")
fi

# ── TPM ──────────────────────────────────────────────────────────────────────
tpm_major="$(cat /sys/class/tpm/tpm0/tpm_version_major 2>/dev/null || true)"
if [[ -n "$tpm_major" ]]; then
    facts+=("$(fact "TPM" "Version $tpm_major" true "A trusted platform module is present and usable")")
elif [[ -e /sys/class/tpm/tpm0 ]]; then
    facts+=("$(fact "TPM" "Present" true "A trusted platform module is present")")
else
    facts+=("$(fact "TPM" "None" false "No trusted platform module, so keys cannot be sealed to this machine")")
fi

# ── Disk encryption ──────────────────────────────────────────────────────────
# Counts LUKS mappings rather than naming them: which volume is encrypted is
# more detail than this readout needs, and device names are not meaningful here.
crypt_count="$(lsblk -o TYPE 2>/dev/null | grep -c '^crypt$' || true)"
[[ "$crypt_count" =~ ^[0-9]+$ ]] || crypt_count=0
if (( crypt_count > 0 )); then
    facts+=("$(fact "Disk encryption" "$crypt_count encrypted volume$( (( crypt_count == 1 )) || printf 's')" true "Data at rest is protected by LUKS")")
else
    facts+=("$(fact "Disk encryption" "None" false "No LUKS volume is unlocked on this machine")")
fi

# ── SELinux ──────────────────────────────────────────────────────────────────
if command -v getenforce >/dev/null 2>&1; then
    case "$(getenforce 2>/dev/null)" in
        Enforcing)  facts+=("$(fact "SELinux" "Enforcing" true "Policy violations are blocked")") ;;
        Permissive) facts+=("$(fact "SELinux" "Permissive" false "Violations are logged but allowed")") ;;
        Disabled)   facts+=("$(fact "SELinux" "Disabled" false "Mandatory access control is off")") ;;
        *)          facts+=("$(fact "SELinux" "Unknown" false "")") ;;
    esac
fi

# ── Firewall ─────────────────────────────────────────────────────────────────
if systemctl list-unit-files firewalld.service >/dev/null 2>&1; then
    if [[ "$(systemctl is-active firewalld 2>/dev/null)" == "active" ]]; then
        facts+=("$(fact "Firewall" "Active" true "firewalld is filtering incoming connections")")
    else
        facts+=("$(fact "Firewall" "Inactive" false "firewalld is installed but not running")")
    fi
fi

printf '[%s]\n' "$(IFS=,; printf '%s' "${facts[*]}")"
