#!/bin/bash
# This file is part of GNU TALER.
# Copyright (C) 2014-2023 Taler Systems SA
#
# TALER is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 2.1, or (at your option) any later version.
#
# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with
# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
#
# @author Florian Dold
# @author Benedikt Muller
# @author Sree Harsha Totakura
# @author Marcello Stanisci
# @author Christian Grothoff
#
#
# Error checking on
set -eu

# Call with target language as first argument.
function make_config() {
  cat >"${BUILDDIR}/conf.py" <<EOF
import sys
import os
sys.path.append(os.path.abspath('_exts'))
needs_sphinx = '1.8.5'
extensions = [
    'sphinx.ext.todo',
    'sphinx.ext.imgmath',
    'sphinx_markdown_builder',
]
templates_path = ['_templates']
source_suffix = {
    '.rst': 'restructuredtext',
}
master_doc = '$VERSION_BASENAME'
project = u'$VERSION_BASENAME'
copyright = u'$COPYRIGHT'
version = '$VERSION_BASENAME'
release = '$VERSION_BASENAME'
language = "$LANGUAGE"
exclude_patterns = ['_build', '_exts', 'cf', 'prebuilt']
locale_dirs = ['$LOCALE_DIR/']
gettext_compact = False
pygments_style = 'sphinx'
html_theme = 'epub'
rst_epilog = ""
html_show_sphinx = False
html_theme_options = {
    "relbar1": "false",
    "footer": "false",
}
html_title = "$TITLE"
html_short_title = "$TITLE"
html_use_index = True
html_show_sphinx = False
latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #'preamble': '',
}
latex_documents = [
    ('$VERSION_BASENAME', '$VERSION_BASENAME.tex',
     '$VERSION_BASENAME', '$VERSION_BASENAME', 'manual'),
]
epub_basename = "$VERSION_BASENAME"
epub_title = "$TITLE"
EOF
}

# Output file given as first argument to stderr, then exit with a failure.
function failcat() {
  cat "$1" 1>&2
  exit 1
}

# defaults
AUTHOR="GNU Taler team"
VERSION="exchange-tos-v0"
LOCALE_DIR=$(taler-config -s "PATHS" -o "LOCALEDIR" -f)
OUTPUT=$(taler-config -s "EXCHANGE" -o "TERMS_DIR" -f)
PAPER="a4"
COPYRIGHT="2014-2023 Taler Systems SA (GPLv3+ or GFDL 1.3+)"
INCREMENTAL=0

# Parse command-line options
while getopts ':a:C:hKi:l:L:o:p:t:' OPTION; do
  case "$OPTION" in
  a)
    AUTHOR="$OPTARG"
    ;;
  C)
    COPYRIGHT="$OPTARG"
    ;;
  h)
    echo 'Supported options:'
    echo '  -a AUTHOR     -- set author header' "(default: $AUTHOR)"
    echo '  -C COPYRIGHT  -- set copyright header' "(default: $COPYRIGHT)"
    echo '  -h            -- print this help'
    echo '  -K            -- rebuild only if input is older than output'
    echo '  -i INPUT      -- input file to convert' "(default: $VERSION)"
    echo '  -l LANGUAGE   -- target language to add'
    echo '  -L LOCALE_DIR -- directory with resources for translation' "(default: $LOCALE_DIR)"
    echo '  -o OUTPUT     -- output directory' "(default: $OUTPUT)"
    echo '  -p PAPER      -- paper format' "(default: $PAPER)"
    echo '  -t TITLE      -- title of the document to generate'
    exit 0
    ;;
  l)
    ADD_LANGUAGE="$OPTARG"
    ;;
  L)
    LOCALE_DIR="$OPTARG"
    ;;
  i)
    VERSION="$OPTARG"
    ;;
  o)
    OUTPUT="$OPTARG"
    ;;
  p)
    PAPER="$OPTARG"
    case "$PAPER" in
    a4 | letter) ;;
    *)
      echo "Error: Paper format '$PAPER' invalid (use 'a4' or 'letter')" 1>&2
      exit 1
      ;;
    esac
    ;;
  t)
    TITLE="$OPTARG"
    ;;
  K)
    INCREMENTAL=1
    ;;
  ?)
    echo "Unrecognized command line option" 1>&2
    exit 1
    ;;
  esac
done

if ! which sphinx-build >/dev/null; then
  echo "Command 'sphinx-build' not found, but required. Please install sphinx." 1>&2
  exit 1
fi

if ! which pandoc >/dev/null; then
  echo "Command 'pandoc' not found, but required. Please install pandoc." 1>&2
  exit 1
fi

if ! which gs >/dev/null; then
  echo "Command 'gs' not found, but required. Please install ghostscript." 1>&2
  exit 1
fi

if ! which pdfroff >/dev/null; then
  echo "Command 'pdfroff' not found, but required. Please install pdfroff/groff." 1>&2
  exit 1
fi

if ! which make >/dev/null; then
  echo "Command 'make' not found, but required. Please install make." 1>&2
  exit 1
fi

# We append ".rst" if needed, remove if given on command-line
# shellcheck disable=SC2001
VERSION=$(echo "${VERSION}" | sed -e "s/\.rst$//")

# Sometimes we just want the basename, not the directory.
VERSION_BASENAME=$(basename "${VERSION}")

BUILDDIR=$(mktemp -d /tmp/taler-terms-XXXXXX)
if [ ! -f "${VERSION}.rst" ]; then
  echo "Error: File '${VERSION}.rst' not found. Please check '-i' option." 1>&2
  exit 1
fi

cp "${VERSION}.rst" "${BUILDDIR}/"

if [ -z ${TITLE+x} ]; then
  TITLE=$(head -n1 "${VERSION}.rst")
  echo "Title automatically set to '$TITLE'" 1>&2
fi

if [ -n "${ADD_LANGUAGE+x}" ]; then
  if ! echo "${ADD_LANGUAGE}" | grep -e '^..$' >/dev/null; then
    echo "Error: Invalid language '${ADD_LANGUAGE}'. Two characters (en, de, fr, ...) expected." 1>&2
    exit 1
  fi
  echo "Adding language files for translations to '${ADD_LANGUAGE}'" 1>&2
  make_config "${ADD_LANGUAGE}"
  sphinx-build \
    -b gettext \
    -D language="${ADD_LANGUAGE}" \
    -d "${BUILDDIR}/.doctrees" \
    "${BUILDDIR}" \
    "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/" \
    &>"${BUILDDIR}/add-language.log" ||
    failcat "${BUILDDIR}/add-language.log"
  if [ -f "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.po" ]; then
    msgmerge --lang="${ADD_LANGUAGE}" \
      --no-location \
      -o "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.mrg" \
      "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.po" \
      "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.pot"
    mv "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.mrg" \
      "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.po"
  else
    mv "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.pot" \
      "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.po"
  fi
  rm -f "${LOCALE_DIR}/${ADD_LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.pot"
  echo "Done" 1>&2
  exit 0
fi

# As a heuristic for incremental builds, we only check the text output file.
if [[ $INCREMENTAL -eq 1 ]]; then
  if [[ "${VERSION}.rst" -ot "${OUTPUT}/buildstamp" ]]; then
    echo "Not rebuilding, input file $VERSION is older than $OUTPUT/buildstamp."
    exit 0
  fi
fi

# shellcheck disable=SC2086
for d in en $(ls -d ${LOCALE_DIR}/?? | grep -v "en" 2>/dev/null || true); do
  LANGUAGE=$(basename "$d")
  if [ "en" != "${LANGUAGE}" ] && [ ! -f "${LOCALE_DIR}/${LANGUAGE}/LC_MESSAGES/${VERSION_BASENAME}.po" ]; then
    echo "Skipping language ${LANGUAGE}: no translation for ${VERSION_BASENAME} found."
    continue
  fi
  echo "Generating files at '$OUTPUT' for ETag '$VERSION_BASENAME' and language '${LANGUAGE}' in '${BUILDDIR}':" 1>&2

  make_config "$LANGUAGE"
  mkdir -p "${OUTPUT}/${LANGUAGE}/"

  LBUILD="sphinx-build -D language=${LANGUAGE} -d ${BUILDDIR}/.doctrees"

  OUTBASE="${OUTPUT}/${LANGUAGE}/${VERSION_BASENAME}"

  echo "$VERSION_BASENAME MD ($LANGUAGE)..." 1>&2
  $LBUILD \
    -b markdown \
    "${BUILDDIR}" \
    "${BUILDDIR}/md" \
    &>"${BUILDDIR}/md-sphinx.log" ||
    failcat "${BUILDDIR}/md-sphinx.log"
  BUILDFILE_MARKDOWN="${BUILDDIR}/md/${VERSION_BASENAME}.md"
  cp "$BUILDFILE_MARKDOWN" "${OUTBASE}.md"

  # Convert the generated Markdown (!) to other formats.

  echo "$VERSION_BASENAME PDF ($LANGUAGE)..." 1>&2
  pandoc \
    -i "$BUILDFILE_MARKDOWN" \
    -o "${OUTBASE}.pdf" \
    --pdf-engine=pdfroff \
    --shift-heading-level-by=-1

  echo "$VERSION_BASENAME HTML ($LANGUAGE)..." 1>&2
  # FIXME: Newer versions of pandic should use
  # --embed-resources --standalone instead of --self-contained
  pandoc \
    -i "$BUILDFILE_MARKDOWN" \
    -o "${OUTBASE}.html" \
    --self-contained \
    --shift-heading-level-by=-1

  echo "$VERSION_BASENAME TXT ($LANGUAGE)..." 1>&2
  pandoc \
    -i "$BUILDFILE_MARKDOWN" \
    -o "${OUTBASE}.txt"
done

if [[ $INCREMENTAL -eq 1 ]]; then
  touch "${OUTPUT}/buildstamp"
fi

echo "Done" 1>&2
exit 0
