#!/usr/bin/env bash

# Build LibrePCB library server content
# - scans libraries/
# - creates ZIP archives
# - copies icons
# - generates API JSON

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

# adjust for targeted major LibrePCB release
LIBREPCB_MAJOR_RELEASE=2

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

cd "$ROOT_DIR"

LIBSRC="libraries"
OUTLIB="public/libs"

API="public/api/v1/libraries/v$LIBREPCB_MAJOR_RELEASE"

BASE_URL="https://librepcb-testlib-server-90447e.pages.git.nrw"

mkdir -p "$OUTLIB"
mkdir -p "$(dirname "$API")"

TMP=$(mktemp)

echo '{' >"$TMP"
echo '  "count": 0,' >>"$TMP"
echo '  "next": null,' >>"$TMP"
echo '  "previous": null,' >>"$TMP"
echo '  "results": [' >>"$TMP"

COUNT=0
FIRST=1

count_files() {
  [ -d "$1" ] && find "$1" -name "$2" | wc -l || echo 0
}

mapfile -t LIBS < <(printf '%s\n' "$LIBSRC"/*.lplib 2>/dev/null | sort)

for LIB in "${LIBS[@]}"; do

  [ -d "$LIB" ] || continue
  [ -f "$LIB/library.lp" ] || continue

  LIBDIR=$(basename "$LIB")
  LIBNAME="${LIBDIR%.lplib}"

  ZIP="$OUTLIB/$LIBDIR.zip"
  ICON="$OUTLIB/$LIBNAME.png"

  echo "Processing $LIBDIR"

  (
    cd "$LIB"
    zip -X -qr "../../$ZIP" . -x ".lock"
  )

  if [ -f "$LIB/library.png" ]; then
    cp "$LIB/library.png" "$ICON"
  fi

  FORMAT_VERSION=$(head -n1 "$LIB/.librepcb-lib" | tr -d '[:space:]')
  if [ "$FORMAT_VERSION" -gt "$LIBREPCB_MAJOR_RELEASE" ]; then
    echo "Skipping $LIBDIR: requires format_version=$FORMAT_VERSION but API is for release v$LIBREPCB_MAJOR_RELEASE"
    continue
  fi
  META="$LIB/library.lp"
 
  UUID=$(head -n1 "$META" | awk '{print $2}')
  NAME=$(grep "(name " "$META" | sed -E 's/.*\(name "(.*)"\).*/\1/')
  DESCRIPTION=$(grep "(description " "$META" | sed -E 's/.*\(description "(.*)"\).*/\1/')
  KEYWORDS=$(grep "(keywords " "$META" | sed -E 's/.*\(keywords "(.*)"\).*/\1/')
  AUTHOR=$(grep "(author " "$META" | sed -E 's/.*\(author "(.*)"\).*/\1/')
  VERSION=$(grep "(version " "$META" | sed -E 's/.*\(version "(.*)"\).*/\1/')
  DEPRECATED=$(grep "(deprecated " "$META" | awk '{print $2}' | tr -d ')')
  URL=$(grep "(url " "$META" | sed -E 's/.*\(url "(.*)"\).*/\1/')
  CREATED=$(grep "(created " "$META" | awk '{print $2}' | tr -d ')')

  DEPS=$(grep -oP '\(dependency \K[^)]+' "$META" 2>/dev/null || true)

  DEPJSON=""
  for D in $DEPS; do
    if [ -z "$DEPJSON" ]; then
      DEPJSON="\"$D\""
    else
      DEPJSON="$DEPJSON, \"$D\""
    fi
  done

  SYMBOLS=$(count_files "$LIB/sym" symbol.lp)
  PACKAGES=$(count_files "$LIB/pkg" package.lp)
  COMPONENTS=$(count_files "$LIB/cmp" component.lp)
  DEVICES=$(count_files "$LIB/dev" device.lp)
  CMPCAT=$(count_files "$LIB/cmpcat" component_category.lp)
  PKGCAT=$(count_files "$LIB/pkgcat" package_category.lp)

  SIZE=$(stat -c %s "$ZIP")
  SHA=$(sha256sum "$ZIP" | cut -d ' ' -f1)

  if [ "$FIRST" -eq 0 ]; then
    echo "," >>"$TMP"
  fi
  FIRST=0

  cat >>"$TMP" <<EOF
    {
      "uuid": "$UUID",
      "name": {
        "default": "$NAME"
      },
      "description": {
        "default": "$DESCRIPTION"
      },
      "keywords": {
        "default": "$KEYWORDS"
      },
      "author": "$AUTHOR",
      "version": "$VERSION",
      "deprecated": $DEPRECATED,
      "url": "$URL",
      "dependencies": [ $DEPJSON ],
      "component_categories": $CMPCAT,
      "package_categories": $PKGCAT,
      "symbols": $SYMBOLS,
      "packages": $PACKAGES,
      "components": $COMPONENTS,
      "devices": $DEVICES,
      "recommended": true,
      "updated_at": "$CREATED",
      "format_version": "$FORMAT_VERSION",
      "icon_url": "$BASE_URL/libs/$LIBNAME.png",
      "download_url": "$BASE_URL/libs/$LIBDIR.zip",
      "download_size": $SIZE,
      "download_sha256": "$SHA"
    }
EOF

  COUNT=$((COUNT + 1))

done

echo "" >>"$TMP"
echo "  ]" >>"$TMP"
echo "}" >>"$TMP"

sed -i "s/\"count\": 0/\"count\": $COUNT/" "$TMP"

mv "$TMP" "$API"

jq . "$API" >/dev/null

echo
echo "Libraries processed: $COUNT"
echo "API generated at: $API"
echo "ZIP files stored in: $OUTLIB"
echo "Done."
