#!/bin/bash
#
# Copyright (C) 2012-2020 SUSE Software Solutions Germany GmbH
#
# Author:
# Frank Sundermeyer <fsundermeyer at opensuse dot org>
# Thomas Schraitle
# Vanessa Wallfahrer
#
# Initialize a working directory to get started with daps
#

#----------------
# Verbose error handling
#
function exit_on_error {
    ccecho "error" "ERROR: ${1}" >&2
    exit 1;
}

function usage {
    cat <<EOF_helptext
$ME --docdir <PATH TO DIRECTORY> [OPTIONS]

Create a working environment for DAPS with an example DocBook document.
Specifying the project directory with --docdir is mandatory, all other
options are optional.
Specifying a name for the document with "--name" is recommended--it will
be used in filenames. Setting the title of the document with "--title"
is also recommended.

Options:

  --docdir=<DIR>
    Path to the project directory under which the DAPS environment will be
    set up. If the directory does not exists, it will be created. Mandatory.

  --dapsroot=<DIR>
    Specify the path to the directory where daps-init can find the template
    files (directory init-templates/). This is only necessary if you have
    installed DAPS in a custom directory. Default: /usr/share/daps

  --date=<YYYY-MM-DD>
    Specify a date in the format YYYY-MM-DD. Will be used to set the
    publication date of the document. (<date/> in the document's info
    section). Default: Current date (<?dbtimestamp format=\"B d, Y\"?>)

  --docbook4
    Create a document in DocBook 4 format (default)

  --docbook5
    Create a document in DocBook 5 format

  --name=<NAME>
    String that will be used in filenames (e.g. when generating PDF or HTML
    output). Only use letters, digits, dashes and underscores [A-Za-z0-9-_].
    Default: daps-example

  --productname=<PRODUCT>
    Specify a name for the product the document describes. Will be used in the
    subtitle of the document (<productname/> in the document's info section)

  --productnumber=<PRODUCT_VERSION>
    Specify a version for the product the document describes. Will be used in
    the subtitle of the document (<productnumber/> in the document's info
    section). Requires --productname.

  --rootelement=<article|book|set>
    DocBook root element of the example document. Currently supported
    are \"book\", \"article\" (default) and \"set\".

  --title=<TITLE>
    Title of the document. Default: "DAPS Example"
EOF_helptext
    exit 0
}

#################################################
# MAIN
#

ME=$(basename "$0")

trap "exit_on_error '\nCaught SIGTERM/SIGINT'" SIGTERM SIGINT

# show help when called with no arguments
[[ -z "$1" ]] && usage

# check for xmlstarlet binary
for _binary in xmlstarlet xml; do
    XMLSTARLET=$(which $_binary 2>/dev/null)
    [[ 0 -eq $? ]] && break
done

[[ -z $XMLSTARLET ]] && exit_on_error "Required package \"xmlstarlet\" is not installed"

#----------------
# Parse the command line arguments

ARGS=$(getopt -o 45d:hn:r:t: -l date:,dapsroot:,docbook4,docbook5,docdir:,help,name:,productname:,productnumber:,rootelement:,title: -n "$ME" -- "$@")

eval set -- "$ARGS"

while true ; do
    case "$1" in
        --dapsroot)
            if [[ -d "$2" ]]; then
                DAPSROOT="$2"
            else
                exit_on_error "dapsroot \"$2\" is not a valid directory."
            fi
            shift 2
            ;;
        --date)
            if [[ -z "$2" ]]; then
                exit_on_error "Date must be set (YYYY-MM-DD)"
            else
                DATE="$2"
                date -d "$DATE" > /dev/null 2>&1 || echo "Wrong date format. Use YYYY-MM-DD"
            fi
            shift 2
            ;;
        --docdir|-d)
            DOC_DIR="$2"
            shift 2
            ;;
        --docbook4|-4)
            DOCBOOKVERSION=4
            shift
            ;;
        --docbook5|-5)
            DOCBOOKVERSION=5
            shift
            ;;
        --help|-h)
            usage
            ;;
        --name|-n)
            if [[ -z "$2" ]]; then
                exit_on_error "Please specify a name"
            elif [[ ! $2 =~ ^[-_A-Za-z0-9]*$ ]]; then
                exit_on_error "The name must not contain characters other than [-_A-za-z0-9]"
            else
                NAME="$2"
            fi
            shift 2
            ;;
        --productname)
            if [[ -z "$2" ]]; then
                exit_on_error "Productname must be set"
            else
                PRODUCTNAME="$2"

            fi
            shift 2
            ;;
        --productnumber)
            if [[ -z "$2" ]]; then
                exit_on_error "Productnumber must be set"
            else
                PRODUCTNUMBER="$2"
            fi
            shift 2
            ;;
        --rootelement|-r)
            if [[ article = "$2" || book = "$2" || "set" = "$2" ]]; then
                ROOTELEMENT="$2"
            else
                exit_on_error "Rootelement must be either \"article\", \"book\" or \"set\""
            fi
            shift 2
            ;;
        --title|-t)
            if [[ -z "$2" ]]; then
                exit_on_error "Title must be set"
            else
                TITLE="$2"
            fi
            shift 2
            ;;
        --) shift ; break ;;
        *) exit_on_error "Wrong parameter: $1" ;;
    esac
done

if [[ -z "$DOC_DIR" ]]; then
  exit_on_error "Please specify a directory with --docdir"
else
  #  strip trailing slash
  DOC_DIR=${DOC_DIR%/}
fi

if [[ -n $PRODUCTNUMBER && -z $PRODUCTNAME ]]; then
    exit_on_error "--productnumber also requires --productname to be specified"
fi

#---------------------
# Defaults:

[[ -z "$DAPSROOT" ]]       && DAPSROOT="/usr/share/daps"
[[ -z "$DATE" ]]           && DATE='<?dbtimestamp format="B d, Y"?>'
[[ -z "$DOCBOOKVERSION" ]] && DOCBOOKVERSION="4"
[[ -z "$NAME" ]]           && NAME="daps-example"
[[ -z "$ROOTELEMENT" ]]    && ROOTELEMENT="article"
[[ -z "$TITLE" ]]          && TITLE="DAPS Example"


TEMPLATE_DIR="${DAPSROOT}/init_templates"

DC_TEMPLATE="${TEMPLATE_DIR}/DC-file.template"
MAIN_TEMPLATE="${TEMPLATE_DIR}/MAIN.db${DOCBOOKVERSION}-$ROOTELEMENT.template"
DC_FILE="${DOC_DIR}/DC-${NAME}"
MAIN="${DOC_DIR}/xml/MAIN-${NAME}.xml"
IMG_DIR="${DOC_DIR}/images/src"


#----------------
# Create the project directory if it does not exist
#

CONT=""
if [[ ! -d $DOC_DIR ]]; then
    while [[ ! $CONT =~ ^[NnYy]$ ]] ; do
        read -e -t 20 -i y -p "$DOC_DIR does not exist. Create it? [y/n] " CONT
        [[ $? -gt 128 ]] && CONT="y" # timeout reached
    done
    if [[ $CONT =~ ^[Yy]$ ]]; then
        mkdir -p "$DOC_DIR" || exit_on_error "Cannot create $DOC_DIR"
    else
        exit_on_error "Aborted by user"
    fi
fi

# Create needed subdirs in DOC_DIR
mkdir -p "${DOC_DIR}"/images/src/{dia,jpg,png,svg,eps,pdf} "${DOC_DIR}/xml" || exit_on_error "Cannot create needed subdirectories in $DOC_DIR"

#----------------
# copy the templates
#

# DC-file
cp "$DC_TEMPLATE" "$DC_FILE" || exit_on_error "Failed to copy $DC_TEMPLATE"
# MAIN
cp "$MAIN_TEMPLATE" "$MAIN" || exit_on_error "Failed to copy $MAIN_TEMPLATE"
# graphics
cp "${DAPSROOT}"/init_templates/example{1,2}.png "${IMG_DIR}/png/" || exit_on_error "Failed to copy images from $TEMPLATE_DIR}"

#----------------
# Adjust the content in the tempate files

# replace placeholder in DC-file with $MAIN
sed -i "s/§§MAIN§§/$(basename "$MAIN")/g" "$DC_FILE"

# replace DATE in MAIN
sed -i "s/§§DATE§§/$DATE/g" "$MAIN"

# replace TITLE in MAIN
sed -i "s/§§TITLE§§/$TITLE/g" "$MAIN"

# insert <productname> and <productnumber> tags

if [[ -n $PRODUCTNAME ]]; then
    if [[ $DOCBOOKVERSION -eq 5 ]]; then
        XPATH="/_:${ROOTELEMENT}/_:info/_:title"
    else
        XPATH="/${ROOTELEMENT}/${ROOTELEMENT}info/title"
    fi

    $XMLSTARLET ed --inplace --append "$XPATH" --type elem --name productname \
        --value "$PRODUCTNAME" "$MAIN"
    if [[ -n $PRODUCTNUMBER ]]; then
        $XMLSTARLET ed --inplace --append "$XPATH" --type elem \
            --name productnumber --value "$PRODUCTNUMBER" "$MAIN"
    fi
fi

#----------------
#
ccecho "result" "Successfully created a DAPS Project at ${DOC_DIR}"
echo "To build a PDF or HTML version of the example document, run:
  daps -d $DC_FILE pdf
or
  daps -d $DC_FILE html"

exit 0;
