#! /bin/bash

t=__wt.$$
t2=__wt.$$.2
trap 'rm -f $t $t2' 0 1 2 3 13 15

# Skip this when building release packages: docs are built separately
test -n "$WT_RELEASE_BUILD" && exit 0

# We require doxygen which may not be installed.
type doxygen > /dev/null 2>&1 || {
	echo "$0 skipped: doxygen not found"
	exit 0
}

. ../RELEASE_INFO

e=0

changelog()
{
	# convert the top-level NEWS file into a change log page in the docs
	(echo "WiredTiger Change Log"
	 echo "====================="
	 echo
	 sed -e 's, \([0-9a-f]\{7\}\) , [\1](https://github.com/wiredtiger/wiredtiger/commit/\1) ,g' \
	     -e 's,\(\(WT\|SERVER\)-[0-9]*\),[\1](https://jira.mongodb.org/browse/\1),g' ../NEWS) > ../src/docs/changelog.md
}

wtperf_config()
{
	# The Linux ed command writes line numbers to stderr, redirect both
	# stdout and stderr to keep things quiet.
	#
	# The OS X cpp program injects line number output in the middle of lines
	# and doesn't stringify #XXX entries; use the -E option to the compiler
	# instead.
	cat ../bench/wtperf/wtperf_opt.i |
	${CC:-cc} -E -DOPT_DEFINE_DOXYGEN - | python wtperf_config.py > $t
	(echo '/START_AUTO_GENERATED_WTPERF_CONFIGURATION/+3,/STOP_AUTO_GENERATED_WTPERF_CONFIGURATION/-1d'
	 echo 'i'
	 echo ''
	 echo '.'
	 echo ".r $t"
	 echo 'a'
	 echo ''
	 echo '.'
	 echo 'w'
	 echo 'q') | ed ../src/docs/wtperf.dox 1>/dev/null 2>/dev/null
}

glossarychk()
{
	(cd ../src/docs && grep '^<tr><td>' arch-glossary.dox | cut -d'>' -f3 | sed -e 's/<.*//') > $t
	sort -f $t > $t2
	if ! diff $t $t2; then
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		echo "arch-glossary.dox entries out of order"
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		e=1
	fi
}

structurechk()
{
	# sections are a global name space for doxygen, and must be uniquely
	# named or you can get the wrong results.  For example, if you have
	# "@section foo ABC" and "@section foo DEF", they will both appear as
	# "ABC" or "DEF".
	(cd ../src/docs &&
	sed -n 's/@section \([^ ]*\)/\1/p' *.dox | sort | uniq -d) > $t
	test -s $t && {
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		echo '@section references that are not uniquely named'
		sed -e 's/^/	/' < $t
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		e=1
	}
	# we want a simple tree structure for navigation, otherwise
	# clicking in the navigation tree can jump to a different point in
	# the tree
	(cd ../src/docs &&
	sed -n 's/@subpage \([^ ]*\)/\1/p' *.dox | sort | uniq -d) > $t
	test -s $t && {
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		echo 'multiple @subpage references for the same page'
		sed -e 's/^/	/' < $t
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		e=1
	}
}

asciichk()
{
    # Make sure there are only ASCII characters in the input files.
    # Odd characters can cause our Python filter to fail.
    (cd ../src/docs && LC_ALL=C grep -n '[^[:print:]	]' *.dox | cat -v) > $t
    test -s $t && {
	echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
	echo 'Non-ASCII content in src/docs/*.dox files is not allowed.'
	sed -e 's/^/	/' < $t
	echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
	e=1
    }
}

spellchk()
{
	# If aspell has been installed, run a spell check.
	type aspell > /dev/null 2>&1 || return

	(cd ../src/docs &&
	# Separate quoted newlines "line\nline" so "nline" is not reported.
	sed -e 's/\("[^"]*\)\\n\([^"]*"\)/\1 \2/' -e 's/[@\\]sic  *\([^ ]*\) //g' *.dox | \
	aspell --encoding=iso-8859-1 --lang=en_US --personal=./spell.ok list) |
	sort -u > $t
	test -s $t && {
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		echo 'Documentation spelling notes'
		echo 'Update src/docs/spell.ok to remove warnings.'
		sed -e 's/^/	/' < $t
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		e=1
	}
}

valid_build()
{
	# Complain if there are pages we don't reference directly.
	sed -n '/<table.*directory/,/\/table/p' < ../docs/pages.html | \
	    grep href > /dev/null && {
		echo 'Unreferenced page: see docs/pages.html for the list.'
		e=1
	}
	classf=`ls ../docs/struct___* 2>/dev/null`
	for c in $classf; do
		echo "$c: Add class to PREDEFINED in src/docs/Doxyfile, then remove docs/*.{html,js} and rebuild"

	done
}

check_docs_data()
{
	python docs.py > $t
	test -s $t && {
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		echo 'Documentation data errors in docs_data.py'
		sed -e 's/^/	/' < $t
		echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
		e=1
	}
}

build()
{
	# Build from scratch on demand.
	[ "$1" -eq 0 ] || (cd .. && rm -rf docs && mkdir docs)

	# Run doxygen to generate warnings for the base HTML documentation.
	#
	# We omit Python because warnings are expected there (the code generated
	# by swig does not have named arguments, but we want to document them
	# as if they do.
	(cd ../src/docs &&
	    (eval cat Doxyfile $filter ; cat <<EOF
QUIET=YES
EOF
) | doxygen -
	test -s doxygen.log && cat doxygen.log) > $t 2>&1
	test -s $t && {
		cat $t
		e=1
	}

	# Copy any needed javascript
	cp ../src/docs/js/* ../docs/

	# Fix up bad links doxygen generates in navtree.js
	(cd ../docs &&
	    sed -i~ -e 's,/\.html,/,' -e 's,\.html\.html,.html,' navtree.js &&
	    rm -f navtree.js~)

	# Any cmapx files that are generated by plantuml need to be referred to
	CMAPX=`find ../src/docs/ -type f -name "*.cmapx" 2>/dev/null`
	if [ "$CMAPX" != '' ]; then
		(cd ../docs
		for f in $CMAPX; do
			b=`echo $f | sed -e 's:.*/::' -e 's/.cmapx$//'`
			for html in `grep -l $b.png *.html`; do
				# There's an image in this HTML file that has a map file
				# generated by plantuml.  Refer to the map by its name
				# and insert the contents of the map into the HTML source.
				sed -e "/<img.*=\"$b[.]png\"/s/\(\"$b[.]png\"\)/\1 usemap=\"#${b}_map\"/" \
				    -e "/<img.*=\"$b[.]png\"/r $f" $html > $html.NEW
				mv $html.NEW $html
			done
		done
		)
	fi
}

clean=0
additional_languages=1
filter="|sed '/PROJECT_BRIEF/s,=.*,=\"$WIREDTIGER_VERSION\",'"
filter="$filter| sed '/PROJECT_NUMBER/s,=.*,=\"Version $WIREDTIGER_VERSION\",'"
while :
	do case "$1" in
	-a)	# Build from scratch
		clean=1
		shift;;
	-l)	# Generate the top-level landing page in ../docs/top
		filter="$filter| sed '/GENERATE_MAN/s,=.*,=NO,';"
		filter="$filter cat top/Doxyfile"
		additional_languages=0
		shift;;
	-p)	# Generate PDFs
		filter="$filter| sed '/GENERATE_LATEX/s,=.*,=YES,'"
		shift;;
	-t)	# Include the TODO list
		filter="$filter| sed '/GENERATE_TODOLIST/s,=.*,=YES,'"
		shift;;
	-v)	# Override the version with <slug> <version string>
		filter="$filter| sed '/HTML_HEADER/s,=.*,= style/header-web.html,'"
		shift
		filter="$filter| sed '/PROJECT_BRIEF/s,=.*,=\"$1\",'"
		shift
		filter="$filter| sed '/PROJECT_NUMBER/s,=.*,=\"$1\",'"
		shift;;
	*)
		break;;
	esac
done

# Generate the change log
changelog

# Generate the list of wtperf configuration options.
wtperf_config

# Spell and structure check the documentation.
asciichk
spellchk
structurechk
glossarychk

# Check the docs data input file.
check_docs_data

# Do not build the doc if we get warnings.
if [ $e != 0 ]; then
    exit $e
fi

# Do not build the documentation if Doxygen version is not compatible.
v=$(doxygen --version)
if [ "$v" != "1.8.17" ]; then
    echo "$0 skipped: unsupported version of doxygen"
    exit 0
fi

# Build the documentation.
build $clean

# Any post-build validity checks we want to make.
valid_build

exit $e
