#!/bin/bash
# generate_sbom.sh
# 此腳本產生 Ubuntu OS 套件清單的 SBOM 表單，
# 表單會以 Unicode 框線呈現美觀、專業的表格，
# 欄位包含 項次、套件、版本、授權、開發者，
# 授權資訊將自 /usr/share/doc/<套件>/copyright（或 .gz）中取得。
# 最後利用 paps 與 ps2pdf 產生 PDF 報告。

# -------------------------------
# 欄位設定：可根據需求調整寬度
WIDTH_INDEX=5
WIDTH_PKG=20
WIDTH_VER=15
WIDTH_LICENSE=20
WIDTH_DEV=30

# 輔助函式：產生一行由某個字元重覆的字串
repeat_char() {
    local char=$1
    local count=$2
    printf "%${count}s" "" | tr " " "${char}"
}

# 產生上框線
top_border="┌$(repeat_char "─" ${WIDTH_INDEX})┬$(repeat_char "─" ${WIDTH_PKG})┬$(repeat_char "─" ${WIDTH_VER})┬$(repeat_char "─" ${WIDTH_LICENSE})┬$(repeat_char "─" ${WIDTH_DEV})┐"
# 產生分隔線（標題與內容間）
mid_border="├$(repeat_char "─" ${WIDTH_INDEX})┼$(repeat_char "─" ${WIDTH_PKG})┼$(repeat_char "─" ${WIDTH_VER})┼$(repeat_char "─" ${WIDTH_LICENSE})┼$(repeat_char "─" ${WIDTH_DEV})┤"
# 產生下框線
bottom_border="└$(repeat_char "─" ${WIDTH_INDEX})┴$(repeat_char "─" ${WIDTH_PKG})┴$(repeat_char "─" ${WIDTH_VER})┴$(repeat_char "─" ${WIDTH_LICENSE})┴$(repeat_char "─" ${WIDTH_DEV})┘"

# 暫存檔案
PACKAGE_LIST=$(mktemp)
TABLE_FILE=$(mktemp)

# 取得已安裝套件名稱與版本，欄位以 tab 分隔
dpkg-query -W -f='${Package}\t${Version}\n' > "$PACKAGE_LIST"

# 開始產生表格內容，先輸出上框線與表頭
{
  echo "$top_border"
  printf "│ %-${WIDTH_INDEX}s │ %-${WIDTH_PKG}s │ %-${WIDTH_VER}s │ %-${WIDTH_LICENSE}s │ %-${WIDTH_DEV}s │\n" "項次" "套件" "版本" "授權" "開發者"
  echo "$mid_border"
} > "$TABLE_FILE"

# 初始化項次
index=1

# 逐行讀取套件資料
while IFS=$'\t' read -r pkg ver; do
  # 取得授權資訊：預設 N/A
  license="N/A"
  if [ -f "/usr/share/doc/${pkg}/copyright" ]; then
      license=$(grep -m1 -i "License:" "/usr/share/doc/${pkg}/copyright" | cut -d: -f2- | sed 's/^[ \t]*//')
  elif [ -f "/usr/share/doc/${pkg}/copyright.gz" ]; then
      license=$(zgrep -m1 -i "License:" "/usr/share/doc/${pkg}/copyright.gz" | cut -d: -f2- | sed 's/^[ \t]*//')
  fi
  [ -z "$license" ] && license="N/A"
  
  # 若授權資訊過長，截取前 WIDTH_LICENSE 個字元
  license=$(echo "$license" | cut -c1-${WIDTH_LICENSE})
  
  # 取得開發者（Maintainer）資訊
  developer=$(apt-cache show "$pkg" 2>/dev/null | grep -m1 -i "maintainer:" | cut -d: -f2- | sed 's/^[ \t]*//')
  [ -z "$developer" ] && developer="N/A"
  developer=$(echo "$developer" | cut -c1-${WIDTH_DEV})

  # 同理，若套件名稱或版本過長，也做截取
  pkg_display=$(echo "$pkg" | cut -c1-${WIDTH_PKG})
  ver_display=$(echo "$ver" | cut -c1-${WIDTH_VER})
  
  # 輸出表格資料列
  printf "│ %${WIDTH_INDEX}d │ %-${WIDTH_PKG}s │ %-${WIDTH_VER}s │ %-${WIDTH_LICENSE}s │ %-${WIDTH_DEV}s │\n" "$index" "$pkg_display" "$ver_display" "$license" "$developer" >> "$TABLE_FILE"
  
  index=$((index + 1))
done < "$PACKAGE_LIST"

# 輸出下框線
echo "$bottom_border" >> "$TABLE_FILE"

# 產生 pango markup 格式的輸出檔，利用 <tt> 呈現等寬字型
OUTPUT_FILE="sbom.txt"
{
  echo "<span font='20' weight='bold'>Ubuntu OS SBOM 報告</span>"
  echo ""
  echo "<tt>"
  cat "$TABLE_FILE"
  echo "</tt>"
} > "$OUTPUT_FILE"

# 轉換成 PDF：paps 產生 PostScript，再透過 ps2pdf 轉成 PDF
PDF_OUTPUT="sbom.pdf"
paps "$OUTPUT_FILE" | ps2pdf - "$PDF_OUTPUT"

# 清除暫存檔
rm "$PACKAGE_LIST" "$TABLE_FILE"

echo "SBOM PDF 產生完成：$PDF_OUTPUT"

