#!/bin/bash
#
# Copyright (C) 2012-2015 SUSE Linux GmbH
#
# Author:
# Frank Sundermeyer <fsundermeyer at opensuse dot org>
#
# Testing DAPS: HTML
#
# NOTE on jsp:
# --jsp is not tested ATM since the original DOcBook stylesheets do not support
#       it
#
# * Does the HTML correctly build?
# * Is an index.hml generated?
# * Does the name retrieved with *-dir-name match the actual result?
# * Are all images linked correctly?
# * Is the draft watermark image included when using the --draft option?
# * Are remarks displayed when using the --remarks option?
# * Is the meta information displayed when using the --meta option?
# * Does the --css switch work?
# * Does the --html5 switch produce XHTML5 ?
# * Does the --clean switch work correctly?
# * Does the --nostatic option work correctly?
# * Can a --nostatic and a regular build be used in turns?
# * Is the --name option correctly implemented?
# * Does the --rootid option work correctly?
# * Are parameters passed with --xsltparam correctly processed?
# * Do the --styleroot and --fb_styleroot options work?
# * Does the automatic fallback to the DoBook stylesheets work?
# * Standard DocBook layout for ressources (CSS):
#   - Is the first CSS file automatically used?
# * Static directory:
#   - Is the static directory copied/linked?
# * Is the --statdir option correctly implemented?
# * Does --single work correctly?

_HTMLDIR_NAME_PATH=""
_LOGFILE=""

source lib/common_functions

header "html"

function oneTimeSetUp() {
    local _LOG_DIR

    # Clean up the build directory
    clean_build_dir all
    # get the profiling directory
    _HTMLDIR_NAME_PATH=$($_DAPSEXEC -d $_DCFILE html-dir-name 2>/dev/null)
    if [ $? -ne 0 ]; then
        exit_on_error " The initial DAPS call to determine the path to the resulting HTML directory failed. Skipping tests"
    fi
    _LOG_DIR=$($_DAPSEXEC -v0 -d $_DCFILE showvariable VARIABLE=LOG_DIR 2>/dev/null)
    if [ $? -ne 0 ]; then
        exit_on_error " The initial DAPS call to determine the LOG file failed. Skipping tests"
    fi
    _LOGFILE=${_LOG_DIR}/make_html.log
}

# Post
# this function is run _after_ the tests are executed
#
function oneTimeTearDown() {
    stats
    # Clean up the build directory
    clean_build_dir all
}

#---------------------------------------------------------------
# TESTS
#---------------------------------------------------------------

#--------------------------------
# * Does the HTML correctly build?
# * Does the name retrieved with *-dir-name match the actual result?
# * Is an index.hml generated?
#
function test_html () {
    local _HTML_BUILD_PATH _BUILD_DIR_NAME

    _HTML_BUILD_PATH=$($_DAPSEXEC -v0 -d $_DCFILE html 2>/dev/null)
    assertTrue \
        ' └─ The html command itself failed' \
        "$?"
    assertTrue \
        " └─ The resulting file/link (${_HTML_BUILD_PATH}/index.html) does not exist." \
        "[ -s $_HTML_BUILD_PATH/index.html -o -L $_HTML_BUILD_PATH/index.html ]"

    _BUILD_DIR_NAME=$_HTML_BUILD_PATH
    assertEquals \
        " └─ The resulting filename does not match the one retrieved with --html-dir-name" \
        "$_HTMLDIR_NAME_PATH" "$_BUILD_DIR_NAME"
}

#--------------------------------
# * Are all images linked correctly?

function test_htmlImages () {
    local _oldIFS _J _IMG _IMAGES_HTML _IMAGES_DAPS _IMG_DIFF _LINKCHECK
    local _MISSING
    declare -a _IMAGES_BUILD
    declare -a _IMAGES_EXPECTED

    # images/ and static/ directories should not contain links
    #
    _LINKCHECK=$(find ${_HTMLDIR_NAME_PATH}/images/ ${_HTMLDIR_NAME_PATH}/static/ -type l)
    assertNull \
        ' └─ image/ and static/ directories contain links (should only be regular files)' \
        "$_LINKCHECK"

    # Check if image links in the HTML point to existing files
    # get list of images using lynx
    #
    _IMAGES_HTML=$(lynx -dump -listonly -image-links ${_HTMLDIR_NAME_PATH}/*.html 2>/dev/null | grep "${_HTMLDIR_NAME_PATH}/images/" 2>/dev/null | sed 's%^\s*[0-9]*\.\s*file://\(localhost\)*%%g' 2>/dev/null | sort -u)

    for _IMG in $_IMAGES_HTML; do
        readlink -e $_IMG >/dev/null 2>&1
        [[ $? = 0 ]] || _MISSING="$_MISSING $_IMG"
    done
    assertNull \
        " └─ Image links in the HTML are dead: $_MISSING" \
        "$_MISSING"
    #
    # Check if list of images retrieved from DAPS matches the ones
    # retrieved from the HTML (see above)
    #
    _IMAGES_DAPS=$($_DAPSEXEC -v0 -d $_DCFILE list-srcfiles --nodc --noent --noxml)
    assertTrue \
        " └─ The command 'list-srcfiles --nodc --noent --noxml' failed" \
        "$?"
    assertNotNull \
        " └─ The command 'list-srcfiles --nodc --noent --noxml' returned an empty string" \
        "_IMAGES_DAPS"
    J=0
    for _IMG in $_IMAGES_DAPS; do
        _IMAGES_EXPECTED[$J]="${_HTMLDIR_NAME_PATH}/images/$(basename $_IMG)"
        # skip JPEGs
        if [[ ${_IMAGES_EXPECTED[$J]##*.} != jpg ]]; then
            _IMAGES_EXPECTED[$J]="${_IMAGES_EXPECTED[$J]%.*}.png"
        fi
        let J++
    done
    _IMAGES_BUILD=( $_IMAGES_HTML )

    # Now we have two lists - "expected images" and "build images". The latter
    # may contain additional images (e.g. for callouts), but the "expected
    # images" all need to appear in "build images". We can check this by using
    # comm: comm -1 -3 <BUILT> <EXPECTED> will show images unique to
    # <EXPECTED> - there should be none. Since comm compares columns, we also
    # need to operate with a modified IFS
    #

    _oldIFS=$IFS IFS=$'\n\t'
    _IMAGES_DIFF=$(comm -1 -3 <(echo "${_IMAGES_BUILD[*]}" | sort -u) <(echo "${_IMAGES_EXPECTED[*]}" 2>/dev/null | sort -u))
    IFS=$_oldIFS
    assertNull \
        " └─ The list of images from DAPS does not match the ones from the HTML" \
        "$_IMAGES_DIFF"

}

#--------------------------------
# * Is the draft watermark image included when using the --draft option?
# * Are remarks displayed when using the --remarks option?
# * Is the meta information displayed when using the --meta option?
#

function test_htmlRemarksDraftMeta () {
    local _BUILD_DIR_NAME _HTML_BUILD_PATH _HTMLDIR_NAME_PATH

    clean_build_dir results

    _HTML_BUILD_PATH=$($_DAPSEXEC -d $_DCFILE --debug html --draft --remarks --meta 2>/dev/null | tail -n 1)
   assertTrue \
       ' └─ Building HTML with --draft --remarks --meta failed' \
       "$?"

   _BUILD_DIR_NAME=$_HTML_BUILD_PATH
   _HTMLDIR_NAME_PATH=$($_DAPSEXEC -v0 -d $_DCFILE html-dir-name --draft --remarks --meta 2>/dev/null)
   assertTrue \
       ' └─ Getting the HTML-dir-name with --draft --remarks --meta failed' \
       "$?"
   assertEquals \
       " └─ The resulting filename does not match the one retrieved with --${_PDFCMD}-name: " \
       "$_HTMLDIR_NAME_PATH" "$_BUILD_DIR_NAME"

   # checking DRAFT mode
   #
   egrep -q -- "background-image.*draft.png" ${_HTML_BUILD_PATH}/index.html 2>/dev/null
   assertTrue \
       ' └─ Generated HTML does not seem to have a DRAFT bg-image' \
       "$?"
   expr "$_HTMLDIR_NAME_PATH" : '.*\(_draft\)' >/dev/null 2>&1
   assertTrue \
       ' └─ String "_draft" does not appear in the HTML-dir-name' \
       "$?"

   # checking REMARKS
   #
   # need to check all HTML files, since index .html does not contain remarks
   #
   grep -q -- "class=\"remark\"" ${_HTMLDIR_NAME_PATH}/*.html 2>/dev/null
   assertTrue \
       ' └─ Generated HTML does not seem to show remarks' \
       "$?"
   expr "$_HTMLDIR_NAME_PATH" : '.*\(_remarks\)' >/dev/null 2>&1
   assertTrue \
       ' └─ String "_remarks" does not appear in the HTML-dir-name' \
       "$?"

   # checking META
   #
   #
   # fs 2015-04-16: Commenting since this is SVN dependent and we no longer
   # use SVN

#   egrep -q -- "--param\s+\"use\.meta=1\"" $_LOGFILE 2>/dev/null
#   assertTrue \
#       ' └─ Param for META is not correctly specified.' \
#       "$?"
#   expr "$_HTMLDIR_NAME_PATH" : '.*\(_meta\)' >/dev/null 2>&1
#   assertTrue \
#       ' └─ String "_meta" does not appear in the HTML-dir-name' \
#       "$?"
}

#--------------------------------
# * Does the --clean switch work correctly?
#

function test_htmlClean () {
    local _TO_CLEAN

    _TO_CLEAN="${_HTMLDIR_NAME_PATH}/.cleantest"

    # Testing --clean by creating a file in the result dir. It should
    # be deleted when running DAPS  with --clean
    #
    mkdir -p ${_HTMLDIR_NAME_PATH}
    touch $_TO_CLEAN >/dev/null 2>&1

    # do not run clean_build_dir here!!

    $_DAPSEXEC -v0 -d $_DCFILE html --clean >/dev/null 2>&1
    assertTrue \
       "' └─ The html command with --clean failed" \
        "$?"
    assertTrue \
        " └─ The result directory does not contain index.html" \
        "[ -s $_HTMLDIR_NAME_PATH/index.html -o -L $_HTMLDIR_NAME_PATH/index.html ]"
    # Test --clean
    assertFalse \
        " └─ The --clean option did not work--the testfile has not been deleted" \
        "[ -f $_TO_CLEAN ]"

    # Test for errors when running two --clean after another
    #
    $_DAPSEXEC -v0 -d $_DCFILE html --clean >/dev/null 2>&1
    assertTrue \
       "' └─ A second run of html --clean failed" \
        "$?"
}

#--------------------------------
# * Does the --css switch work?
# * Does the --html5 switch produce XHTML5 ?
#

function test_htmlCSS_HTML5 () {
    local _CSS_BUILD _CSS_FILE _CSS_PATH

    _CSS_FILE="test.css"
    _CSS_PATH="${_DOC_DIR}/xml/${_CSS_FILE}"
    _CSS_BUILD="${_HTMLDIR_NAME_PATH}/static/css/${_CSS_FILE}"

    clean_build_dir profiles
    clean_build_dir results

    $_DAPSEXEC -v0 -d $_DCFILE html --html5 --css $_CSS_PATH >/dev/null 2>&1

    assertTrue \
       "' └─ The html command with --html5 and --css failed" \
        "$?"

    # Test for HTML5
    #
    grep -q "<\!DOCTYPE html>" ${_HTMLDIR_NAME_PATH}/index.html 2>/dev/null
    assertTrue \
        ' └─ The resulting HTML does not have a valid XHTML5 Doctype declaration.' \
        "$?"
    # Test CSS
    #
    assertTrue \
        " └─ The result directory does not contain ${_CSS_BUILD}" \
        "[ -f ${_CSS_BUILD} -o -L ${_CSS_BUILD} ]"
    grep -q "static/css/${_CSS_FILE}" ${_HTMLDIR_NAME_PATH}/index.html 2>/dev/null
    assertTrue \
        ' └─ The resulting HTML does not include a link to static/css/${_CSS_FILE}.' \
        "$?"
}

#--------------------------------
# * Does the --nostatic option work correctly?
# * Can a --nostatic and a regular build be used in turns?
#
function test_htmlStatic () {
    local _CSS_BUILD _CSS_FILE _CSS_PATH _IMG _IMAGES_HTML _LINKCHECK
    local _MISSING _STYLEIMAGES

    _CSS_FILE="test.css"
    _CSS_PATH="${_DOC_DIR}/xml/${_CSS_FILE}"
    _CSS_BUILD="${_HTMLDIR_NAME_PATH}/static/css/${_CSS_FILE}"

    clean_build_dir results

    $_DAPSEXEC -v0 -d $_DCFILE html --nostatic --css $_CSS_PATH >/dev/null 2>&1
    assertTrue \
        ' └─ The html command itself failed' \
        "$?"
    # images/ and static/ directories should only contain regular files
    #
    _LINKCHECK=$(find ${_HTMLDIR_NAME_PATH}/images/ ${_HTMLDIR_NAME_PATH}/static/ -type f)
    assertNull \
        ' └─ image/ and static/ directories contain regular files (should only contain links)' \
        "$_LINKCHECK"
        #
    # Check if image links in the HTML point to existing files
    # get list of images using lynx
    #
    _IMAGES_HTML=$(lynx -dump -listonly -image-links ${_HTMLDIR_NAME_PATH}/*.html 2>/dev/null | grep "${_HTMLDIR_NAME_PATH}/images/" 2>/dev/null | sed 's%^\s*[0-9]*\.\s*file://\(localhost\)*%%g' 2>/dev/null | sort -u)

    for _IMG in $_IMAGES_HTML; do
        readlink -e $_IMG >/dev/null 2>&1
        [[ $? = 0 ]] || _MISSING="$_MISSING $_IMG"
    done
    assertNull \
        " └─ Image links in the HTML are dead: $_MISSING" \
        "$_MISSING"
    #
    # Check if static/images and $_STYLEIMG contain the same files
    #
    _STYLEIMAGES=$($_DAPSEXEC -v0 -d $_DCFILE showvariable VARIABLE=STYLEIMG 2>/dev/null)
    diff -qr ${_HTMLDIR_NAME_PATH}/static/images $_STYLEIMAGES >/dev/null 2>&1
    assertTrue \
        " └─ The build static directory differs from the one provided by the stylesheets." \
        "$?"
    #
    # Check if the css files match
    #
    diff -q $_CSS_PATH $_CSS_BUILD >/dev/null 2>&1
    assertTrue \
        " └─ The build CSS file differs from the one provided with --css." \
        "$?"

    # Are the nostatic files correctly overwritten by a regular build?
    #
    $_DAPSEXEC -v0 -d $_DCFILE html --css $_CSS_PATH >/dev/null 2>&1

    _LINKCHECK=$(find ${_HTMLDIR_NAME_PATH}/images/ ${_HTMLDIR_NAME_PATH}/static/ -type l)
    assertNull \
        ' └─ image/ and static/ directories still contain links after a regular run' \
        "$_LINKCHECK"

    # Are the linked files correctly overwritten by a --nostatic build?
    #
    $_DAPSEXEC -v0 -d $_DCFILE html --nostatic --css $_CSS_PATH >/dev/null 2>&1

    _LINKCHECK=$(find ${_HTMLDIR_NAME_PATH}/images/ ${_HTMLDIR_NAME_PATH}/static/ -type f)
    assertNull \
        ' └─ image/ and static/ directories still contain regular files after a --nostatic run' \
        "$_LINKCHECK"

}

#--------------------------------
# * Is the --name option correctly implemented?
#
function test_htmlNAME () {
    local _BUILD_SUBDIR_NAME _HTML_BUILD_PATH _HTMLDIR_NAME_PATH _NAME
    _NAME="testsuite"

    clean_build_dir results

    _HTML_BUILD_PATH=$($_DAPSEXEC -v0 -d $_DCFILE html --name $_NAME 2>/dev/null)
    assertTrue \
        " └─ Building a html document with --name failed " \
       "$?"

    _BUILD_SUBDIR_NAME=$(basename $_HTML_BUILD_PATH)
    assertEquals \
        ' └─ The subdirectory name of the build result does not match the string given with --name:' \
        "$_NAME" "$_BUILD_SUBDIR_NAME"

    _HTMLDIR_NAME_PATH=$($_DAPSEXEC -v0 -d $_DCFILE html-dir-name --name $_NAME 2>/dev/null)
    assertTrue \
        ' └─ Getting the HTML-dir-name with --name failed' \
        "$?"
}

#--------------------------------
# * Does the --rootid option work correctly?
# * Are parameters passed with --xsltparam correctly processed?
#
function test_htmlRootidXsltparam () {
    local _BUILD_SUBDIR_NAME _BUILD_SUBDIR_ROOTID _FILECOUNT _FILECOUNT_EXPECTED _HTML_BUILD_PATH
    local  _ROOTID _XSLTPARAM

    _ROOTID=appendix
    _FILECOUNT_EXPECTED=1
    # will generate HTML files with .xhtml extension
    _XSLTPARAM="'--param spacing.paras=1'"

    clean_build_dir results

    _HTML_BUILD_PATH=$($_DAPSEXEC -d $_DCFILE --debug html --rootid $_ROOTID --xsltparam="$_XSLTPARAM" 2>/dev/null | tail -n 1)
    assertTrue \
        ' └─ Building a html document with --rootid and --xsltparam failed ' \
       "$?"

    egrep -q -- "--stringparam\s+\"rootid=$_ROOTID\"" $_LOGFILE 2>/dev/null
    assertTrue \
        ' └─ Stringparam for ROOTID is not correctly specified when generating the FO-file' \
        "$?"
    _BUILD_SUBDIR_NAME=$(basename $_HTML_BUILD_PATH)
    assertEquals \
        ' └─ The resulting HTML dirname does not match the ROOTID:' \
        "$_ROOTID" "$_BUILD_SUBDIR_NAME"

    # check HTML file count - should be one real file
    # (only make sense for HTML, since single-html is only one file anyway)
    #
    _FILECOUNT=$(find $_HTML_BUILD_PATH -type f -name "*.html" | wc -l)
    assertEquals \
        ' └─ Wrong HTML file count:' \
        "$_FILECOUNT_EXPECTED" "$_FILECOUNT"

    # If a ROOTID was specified, no index.html is  generated by the stylesheets
    # In this case we manually generate one in the makefile
    # Here we test if a link points to a real file
    #
    [[ -L $_HTML_BUILD_PATH/index.html ]] && readlink -e $_HTML_BUILD_PATH/index.html >/dev/null 2>&1
    assertTrue \
        " └─ The resulting link (${_HTML_BUILD_PATH}) does not point to an existing file" \
        "$?"

    # check xsltparam
    egrep -q -- "$_XSLTPARAM" $_LOGFILE 2>/dev/null
    assertTrue \
        ' └─ Param for XSLTPARAM is not correctly specified when generating HTML' \
        "$?"
}

#--------------------------------
# * Do the --styleroot and --fb_styleroot options work?
# * Does the automatic fallback to the DoBook stylesheets work?
# * Standard DocBook layout for ressources (CSS):
#   - Is the first CSS file automatically used?
#     -> images from the resources directory have already been tested in
#        htmlImages and htmlStatic
# * Static directory:
#   - Is the static directory copied/linked?
# * Is the --statdir option correctly implemented?
#

function test_htmlStylerootStatdir () {
    local _ALT_STATIC_DIR _CSS_FILE _STANDARD_CSS _STATIC_DIR

    _CSS_FILE="style.css"
    _STANDARD_CSS="${_STANDARD_STYLES}/xhtml/$_CSS_FILE"
    _STATIC_DIR="${_STATIC_STYLES}/static"
    _ALT_STATIC_DIR="${_ALT_STATIC_STYLES}/static"

    clean_build_dir results

    # Testing Fallback Styleroot by specifying a wrong Styleroot dir
    #

    $_DAPSEXEC -d $_DCFILE --styleroot=${_DOC_DIR} --fb_styleroot=${_STANDARD_STYLES} --debug html >/dev/null 2>&1
    egrep -q -- "--stylesheet /.*/${_STANDARD_STYLES}" $_LOGFILE 2>/dev/null
    assertTrue \
        " └─ The Fallback Styleroot specified on the command line was not used." \
        "$?"

    clean_build_dir results

    # Testing automatic Fallback to _DB_STYLES by specifying a wrong
    # Styleroot dir with no Fallback
    #
    $_DAPSEXEC -d $_DCFILE --styleroot=${_DOC_DIR} --debug html >/dev/null 2>&1
    grep -q -- "--stylesheet ${_DB_STYLES}" $_LOGFILE 2>/dev/null
    assertTrue \
        " └─ The automatic DocBook Fallback Styleroot was not used." \
        "$?"

    clean_build_dir results

    # Testing Styleroot specified with --styleroot
    #
    $_DAPSEXEC -d $_DCFILE --styleroot ${_STANDARD_STYLES} --debug html >/dev/null 2>&1
    egrep -q -- "--stylesheet /.*/${_STANDARD_STYLES}" $_LOGFILE 2>/dev/null
    assertTrue \
        " └─ The Styleroot specified on the command line was not used." \
        "$?"

    # Standard DocBook layout: Is the first CSS file automatically used?
    #
    diff -q $_STANDARD_CSS ${_HTMLDIR_NAME_PATH}/static/css/$_CSS_FILE >/dev/null 2>&1
     assertTrue \
        " └─ $_STANDARD_CSS was not correctly copied to the build directory." \
        "$?"

    clean_build_dir results

    # Is the statdir correctly copied?
    #
    $_DAPSEXEC -v0 -d $_DCFILE --styleroot ${_STATIC_STYLES} html >/dev/null 2>&1

    diff -qr ${_HTMLDIR_NAME_PATH}/static ${_STATIC_DIR} >/dev/null 2>&1
    assertTrue \
        " └─ The build static directory differs from the one provided by the stylesheets." \
        "$?"

    clean_build_dir results

    # Is the --statdir option correctly implemented?
    #
    $_DAPSEXEC -v0 -d $_DCFILE --styleroot ${_STATIC_STYLES} html --statdir=$_ALT_STATIC_DIR >/dev/null 2>&1

    diff -qr ${_HTMLDIR_NAME_PATH}static ${_ALT_STATIC_DIR} >/dev/null 2>&1
    assertTrue \
        " └─ The build static directory differs from the one provided with --statdir." \
        "$?"
}

#--------------------------------
# * Does --single work correctly?
#

function test_htmlSingle () {
    local _FILE_COUNT_BUILD _FILE_COUNT_EXPECTED _HTML_BUILD_PATH _HTML_NAME_PATH

    clean_build_dir results

    # single html creates one HTML file plus the index.html link
    _FILE_COUNT_EXPECTED=2

    _HTML_BUILD_PATH=$($_DAPSEXEC -d $_DCFILE html --single 2>/dev/null | tail -n 1)
    assertTrue \
        ' └─ Building single HTML with --single failed' \
       "$?"
    assertTrue \
        " └─ The resulting file (${_HTML_BUILD_PATH}) does not exist" \
        "[ -s $_HTML_BUILD_PATH ]"

   _HTML_NAME_PATH=$($_DAPSEXEC -v0 -d $_DCFILE html-dir-name --single 2>/dev/null)
   assertTrue \
       ' └─ Getting the HTML directory name with --single failed' \
       "$?"
   assertEquals \
       " └─ The resulting directory name does not match the one retrieved with html-dir-name: " \
       "$_HTML_NAME_PATH" "$_HTML_BUILD_PATH"

   _FILE_COUNT_BUILD=$(find $_HTML_NAME_PATH -name "*.html" 2>/dev/null | wc -l)
   assertEquals \
       " └─ The resulting directory contains too many html files: " \
       "$_FILE_COUNT_EXPECTED" "$_FILE_COUNT_BUILD"
}

# source shUnit2 test
source $_SHUNIT2SRC
