#!/bin/bash
# Copyright (C) 2016 by SUSE LINUX GmbH.
# Author: Fabian Vogt <fvogt@suse.com>, 2016.
# This program is under GPL license. See COPYING file for details.

DEFAULT_CATALOG="/etc/xml/catalog-d.xml"
DEFAULT_GENDIR="/etc/xml/catalog.d"
CATALOG_SCHEMA="/usr/share/xml/xmlcatalog/schema/rng/catalog.rng"
SKIPVALID=

# Print help or version
case $1 in
    --skipvalid)
      SKIPVALID=1
      shift
    ;;
    --version)
      echo "update-xml-catalog 0.7.2 (part of sgml-skel)"
      exit 0
    ;;
    -h|--help)
      echo -e "update-xml-catalog 0.7.2 (part of sgml-skel)\n\
\n\
Generates ${DEFAULT_CATALOG} from the files in ${DEFAULT_GENDIR}\n\
The output file can be overwritten by setting the first parameter,\n\
the input directory as second parameter. Examples:\n\
\n\
update-xml-catalog /tmp/tmpcatalog.xml\n\
update-xml-catalog /tmp/tmpcatalog.xml /tmp/tmpcatalog.d"
      exit 0
    ;;
    --)
      shift
    ;;
esac

CATALOG=${1:-$DEFAULT_CATALOG}
GENDIR=${2:-$DEFAULT_GENDIR}

# die: Echo arguments to stderr and exit with 1
die() { echo "$@" 1>&2 ; exit 1; }

# Basic checks
[ -w "$CATALOG" ] || [ -w "$(dirname -- "$CATALOG")" ] || die "No permission to write catalog"
[ -d "$GENDIR" ] || die "Source directory does not exist"

# Create temporary file
tmpfile=$(mktemp) || die "Could not create temporary file"
# Remove it on exit
trap rm\ -f\ "$tmpfile" EXIT

chmod -- 644 "$tmpfile" || die "Could not set permissions"

# Write catalog header
cat > "$tmpfile" <<EOF
<?xml version="1.0"?>
<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<!-- Bogus entry to avoid this being empty -->
<uri name="http://this.does/not#exist" uri="file:///does/not/exist/either"/>
EOF

[ $? -eq 0 ] || die "cat failed"

# Use this for catalog validation
XMLLINT_RELAXNG=
[ -z "$SKIPVALID" ] && [ -f "$CATALOG_SCHEMA" ] && XMLLINT_RELAXNG=--relaxng\ "$CATALOG_SCHEMA"

# Write the catalog entries:
# List all non-hidden files in GENDIR recursively, sort the paths and pass them to xmllint.

err=$(find "$(realpath -- "$GENDIR")" -type f -not -path '*/\.*' -print0 | sort -z | \
        xargs --no-run-if-empty -0 xmllint $XMLLINT_RELAXNG --xpath "/*/node()" 2>&1 >> "$tmpfile")

if [ $? -ne 0 ]; then
  echo "$err" >&2
  die "xmllint failed"
fi

# Write the catalog footer
echo "</catalog>" >> "$tmpfile" || die "echo failed"

# If validation skipped or RNG schema does not exist, skip validation
if [ -z "$SKIPVALID" ] && [ -f "$CATALOG_SCHEMA" ]; then
  if ! err=$(xmllint --noout $XMLLINT_RELAXNG "$tmpfile" 2>&1); then
    echo "$err" >&2
    die "Generated catalog not valid"
  fi
fi

# Finally rename
mv -- "$tmpfile" "$CATALOG" || die "mv failed"
