#!/usr/bin/env bash

#set -x

# Usage: write-user-docs [TOOLS]
#
# This script writes/updates the user documentation.  User docs come from
# three places: each tool's POD (pod2rst is used to convert their POD docs
# to RST), static .rst file (docs/*.rst), and most head1 sections in
# docs/percona-toolkit.pod (also converted writh pod2rst; this file is needed
# in .pod form because it's used to make the percona-toolkit man page).
#
# Run this script from any directory in the branch whose user docs you want
# to build.  For example, to build user docs in the 2.0 branch:
#   $ cd ~dev/perona-toolkit/2.0
#   $ util/write-user-docs
# Unlike other scripts, this one does *not* use PERCONA_TOOLKIT_BRANCH.
#
# After all the RST files have been written, this script runs `make html'
# in config/sphinx-build/ (which has a Makefile) to build the online HTML
# docs, which are saved in docs/user/html.
#
# If no tools are specified on the command line, then docs for bin/* are
# written (plus all the extra sections).
#
# To rewrite all user docs from scratch:
#   rm -rf docs/user/*
#   util/write-user-docs
#
# Exits 0 on success, else 1 on warnings and errors.

# ############################################################################
# Parsing options
# ############################################################################

usage()
{
  echo "This script writes/updates the user documentation.

        Usage: write-user-docs [ -h ] [ -p ] [ -t ] [TOOLS]

        If no option (html, pdf) specified, builds both html and pdf.

        -h builds docs in html
        -t builds docs in html with new theme
        -p builds pdf doc

        TOOLS: If no tools are specified on the command line, then docs for bin/* are written (plus all the extra sections).
        "
  exit 2
}

TEMP=$(getopt hpt $*)

if [ $? -ne 0 ]; then
  usage
fi

eval set -- "$TEMP"
unset TEMP

while true; do
  case "$1" in
    -h)
        MAKE_HTML="true"
        MAKE_THTML="false"
        shift
        continue
    ;;
    -t)
        MAKE_THTML="true"
        MAKE_HTML="false"
        shift
        continue
    ;;
    -p)
        MAKE_PDF="true"
        shift
        continue
    ;;
    --)
        shift
        break
    ;;
    *)
        echo 'Internal error!' >&2
        usage
    ;;
  esac
done

# if both specified or none, build both
if [[ "$MAKE_HTML" == "$MAKE_PDF" ]]; then
    MAKE_HTML="true"
    MAKE_PDF="true"
fi

# ############################################################################
# Standard startup, find the branch's root directory
# ############################################################################

exit_status=0

die() {
   echo "$1" >&2
   exit 1
}

warn() {
   echo "$1" >&2
   exit_status=1
}

cwd=$PWD
while [ ! -f Makefile.PL ] && [ $(pwd) != "/" ]; do
   cd ..
done
if [ ! -f Makefile.PL ]; then
   die "Cannot find the root directory of the Percona Toolkit branch"
fi
BRANCH=`pwd`
cd $cwd

# ############################################################################
# Paths
# ############################################################################

DOCS_DIR=$BRANCH/docs
RST_DIR=$DOCS_DIR/user

# ############################################################################
# Subroutines
# ############################################################################

fix_html () {
   local name="$1"
   perl -MFile::Basename=basename -le '
      my $f    = shift;
      my $tool = basename($f);
      $tool    =~ s/\.html//;
      my $out = do { open my $fh, q{<}, $f or die "$f: $!"; local $/; <$fh> };
      $out =~ s{
\Q<dt id="\E(cmdoption-$tool--)\Q">\E\s*
\Q<tt class="descname">--</tt><tt class="descclassname">\E([^<]+)
\Q</tt><a class="headerlink" href="\E[^"]+"
}{<dt id="$1$2">
<tt class="descname">--$2</tt><tt class="descclassname"></tt><a class="headerlink" href="#$1$2"}xg;
      open my $fh, q{>}, $f or die "Cannot open $f for writing: $!";
      print { $fh } $out;
      close $fh or die "Cannot close $f: $!";
   ' "$RST_DIR/html/$name.html"
}

write_rst() {
   local file="$1"
   local tool="$(basename $1)"
   if [ ! -f $file ]; then
      warn "$file does not exist"
      return
   fi

   if [ -h $file ]; then
      local link="$(readlink $file)"
      echo "
.. program:: ${tool}

============================
:program:\`${tool}\`
============================

NAME
====

:program:\`$(basename $file)\` is a symbolic link to ${link}. Please read documentation for ${link}.

" > $RST_DIR/$tool.rst
   else
      $BRANCH/util/pod2rst-fixed.packed $file > $RST_DIR/$tool.rst
      if [ $? -eq 0 ]; then
         echo "Wrote $RST_DIR/$tool.rst"
      else
         die "Error writing $RST_DIR/$tool.rst"
      fi
   fi
}

# Parse the head1 sections from percona-toolkit.pod and write them as
# individual .rst files, except the sections in the grep -Ev below.
# For example, head1 SYSTEM REQUIREMENTS becomes system_requirements.rst.
# These sections are included in index.rst.
write_sections() {

   # Grep head1 sections from percona-toolkit.pod, except a few, and
   # change spaces to _ so the for..do loop doesn't treat "SYS REQS"
   # as two sections.
   sections=$(grep '^=head1' $DOCS_DIR/percona-toolkit.pod | sed -e 's/=head1 //' -e 's/ /_/g' | grep -Ev "^NAME|DESCRIPTION|TOOLS")

   for section in $sections; do
      # Put spaces back in the section's name.
      header=$(echo $section | sed -e 's/_/ /g')

      # Convert the section name to a simple filename.
      filename=$(echo $section | sed -e 's/,//g' -e 's/[()]//g' | tr "[:upper:]" "[:lower:]");

      # Extract the section as POD.
      local start_line=$(grep --line-number "^=head1 $header" $DOCS_DIR/percona-toolkit.pod | cut -d':' -f1)
      if [ -z "$start_line" ]; then
         die "Cannot find $from in $DOCS_DIR/percona-toolkit.pod"
      fi

      tail -n +$start_line $DOCS_DIR/percona-toolkit.pod | awk "BEGIN { getline; print \$0 } /^=head1|=cut/ { exit } { print }" > /tmp/$filename.pod

      # Convert POD to RST and remove all the Perl highlight blocks.
      $BRANCH/util/pod2rst-fixed.packed /tmp/$filename.pod --no-fix | sed -e 's/.. highlight:: perl//g' > /tmp/$filename.tmp

      # Remove extra blank lines.
      cat -s /tmp/$filename.tmp > $RST_DIR/$filename.rst

      # Remove tmp files.
      rm /tmp/$filename.pod
      rm /tmp/$filename.tmp

      echo "Wrote $RST_DIR/$filename.rst"
   done
}

# ############################################################################
# Script starts here
# ############################################################################

WRITE=${WRITE:-1}
if [ $WRITE -eq 1 ]; then
   if [ $# -gt 0 ]; then
      for tool; do
         write_rst $tool
      done
   else
      for tool in `ls $BRANCH/bin/*`; do
         write_rst $tool
      done
   fi

   # Parse and write certain parts of percona-toolkit.pod.
   write_sections

   # Copy all static .rst files, like index.rst.
   cp $DOCS_DIR/*.rst $RST_DIR/
   echo "Copied $DOCS_DIR/*.rst to $RST_DIR"
fi

BUILD=${BUILD:-1}
if [ $BUILD -eq 1 ]; then
   cd $BRANCH/config/sphinx-build

   if [ "${MAKE_HTML}" = "true" ]; then
      make html
   fi

   if [ "${MAKE_PDF}" = "true" ]; then
      make latexpdf
   fi

   if [ "${MAKE_THTML}" = "true" ]; then
      make thtml
   fi

   exit_status=$(( exit_status | $? ))
fi

if [ $# -gt 0 ]; then
   for tool; do
      name="$(basename $tool)"
      fix_html $name
   done
else
   for tool in `ls $BRANCH/bin/*`; do
      name="$(basename $tool)"
      fix_html $name
   done
fi


exit $exit_status
