#!/usr/bin/env bash
set -Eeuo pipefail

# Copyright 2026 erik@ctan.org
#
# This work may be distributed and/or modified under the conditions of the
# LaTeX Project Public License, either version 1.3c or any later version.

if [[ "$#" -ne 2 ]]; then
    printf 'Usage: %s INPUT.pdf OUTPUT.pdf\n' "${0##*/}" >&2
    exit 2
fi

input_pdf=$1
output_pdf=$2

for command_name in basename dirname gs inkscape install mkdir mktemp pdfinfo \
    pdfseparate pdffonts pdfunite perl sed sha256sum; do
    if ! command -v "$command_name" >/dev/null 2>&1; then
        printf 'Required command not found: %s\n' "$command_name" >&2
        exit 1
    fi
done

if [[ ! -f "$input_pdf" ]]; then
    printf 'Input PDF not found: %s\n' "$input_pdf" >&2
    exit 1
fi

page_count=$(pdfinfo "$input_pdf" | sed -n 's/^Pages:[[:space:]]*//p')
if [[ ! "$page_count" =~ ^[1-9][0-9]*$ ]]; then
    printf 'Could not determine a valid page count for %s.\n' "$input_pdf" >&2
    exit 1
fi

output_dir=$(dirname -- "$output_pdf")
mkdir -p -- "$output_dir"
work_dir=$(mktemp -d "${TMPDIR:-/tmp}/sansforgetica-outline.XXXXXX")
trap 'rm -rf -- "$work_dir"' EXIT

pdfseparate "$input_pdf" "$work_dir/source-%d.pdf"

outlined_pages=()
for ((page_number = 1; page_number <= page_count; page_number++)); do
    source_page="$work_dir/source-$page_number.pdf"
    outlined_page="$work_dir/outlined-$page_number.pdf"
    inkscape \
        --pdf-poppler \
        --pdf-page=1 \
        --export-area-page \
        --export-text-to-path \
        --export-filename="$outlined_page" \
        "$source_page" >/dev/null 2>&1
    outlined_pages+=("$outlined_page")
done

combined_output="$work_dir/combined.pdf"
temporary_output="$work_dir/$(basename -- "$output_pdf")"
pdfunite "${outlined_pages[@]}" "$combined_output"

# Inkscape and pdfunite use volatile creation data and document identifiers.
# Rewrite the combined PDF with a fixed build timestamp, then derive a stable
# PDF identifier from the otherwise normalized bytes. The replacement is in
# the trailer, after the cross-reference table, so byte offsets stay valid.
source_date_epoch=${SOURCE_DATE_EPOCH:-1789862400}
SOURCE_DATE_EPOCH="$source_date_epoch" gs \
    -q \
    -dSAFER \
    -dBATCH \
    -dNOPAUSE \
    -dDeterministicID=true \
    -dPreserveMetadata=false \
    -sDEVICE=pdfwrite \
    -dCompatibilityLevel=1.5 \
    -sOutputFile="$temporary_output" \
    "$combined_output"

zero_id=00000000000000000000000000000000
ZERO_ID="$zero_id" perl -0777pi -e '
    $replacement = "/ID [<$ENV{ZERO_ID}><$ENV{ZERO_ID}>]";
    $count = s{/ID\s*\[\s*<[0-9A-Fa-f]{32}>\s*<[0-9A-Fa-f]{32}>\s*\]}
               {$replacement}g;
    die "Expected exactly one PDF trailer ID, found $count\n" if $count != 1;
' "$temporary_output"

read -r normalized_hash _ < <(sha256sum -- "$temporary_output")
document_id=${normalized_hash:0:32}
document_id=${document_id^^}
DOCUMENT_ID="$document_id" ZERO_ID="$zero_id" perl -0777pi -e '
    $needle = "/ID [<$ENV{ZERO_ID}><$ENV{ZERO_ID}>]";
    $replacement = "/ID [<$ENV{DOCUMENT_ID}><$ENV{DOCUMENT_ID}>]";
    $count = s/\Q$needle\E/$replacement/g;
    die "Expected exactly one normalized PDF trailer ID, found $count\n"
        if $count != 1;
' "$temporary_output"

font_rows=$(pdffonts "$temporary_output" | sed -n '3,$p' | sed '/^[[:space:]]*$/d')
if [[ -n "$font_rows" ]]; then
    printf 'Outlined PDF still contains fonts:\n%s\n' "$font_rows" >&2
    exit 1
fi

install -m 0644 -- "$temporary_output" "$output_pdf"
printf 'Created vector-outlined PDF: %s\n' "$output_pdf"
