# -*-Shell-script-*-
#
# Copyright (C) 2015-2020 SUSE Software Solutions Germany GmbH
#
# Author:
# Frank Sundermeyer <fsundermeyer at opensuse dot org>
#
###########################################################################
#
# PACKAGING unpack-locdrop
#
# Subcommand: unpack-locdrop only
#
# unpack a localization drop packages source.
# Files listed in manifest_trans.txt will be extracted from the given tarball
# Files listed in manifest_notrans will be linked/copied from the notrans
# directory specified with --notrans-dir
#
###########################################################################funct

function unpack-locdrop {
    local SHORT_OPTS LONG_OPTS SUB_CMD
    local ALL_TRANS_FILES ALL_NOTRANS_FILES DCFILE_LIST ENTITIES
    local FILES_IN_TAR FILES_TRANS_IN_MANIFEST FILES_MANIFEST_ONLY
    local FILES_TRANS_EXTRACT LINK_NOTRANS_FILES MANIFEST_TRANS
    local MANIFEST_NOTRANS MFT_TRANS_SUFF MFT_NOTRANS_SUFF NO_DCFILE_LIST
    local NO_EXIFTOOL NO_OPTIPNG XML_FILE_LIST
    local -a ALL_MANIFEST_NOTRANS_FILES ALL_MANIFEST_TRANS_FILES

    MFT_TRANS_SUFF=manifest_trans.txt
    MFT_NOTRANS_SUFF=manifest_notrans.txt

    SUB_CMD=$1
    shift

    SHORT_OPTS="h"
    LONG_OPTS="help,notrans-dir:,not-validate-tables,optipng,output-dir:,remove-dm,trans-files:"

    parse_args "$SHORT_OPTS" "$LONG_OPTS" "$SUB_CMD" "$@"
    eval set -- "$P_REMAIN_ARGS"

    #------ Computing the values returned from the parser -----
    if [[ 1 -eq $P_HELP ]]; then
        help_scmd_head "$SUB_CMD" "${HELP_SUBCOMMAND[$SUB_CMD]}"
        help_trans-files
        help_help
        help_notrans-dir
        help_not-validate-tables
        help_optipng
        help_output-dir
        help_remove-dm
        echo
        exit 0
    fi

    if [[ -z "$P_TRANS_FILES" ]]; then
    exit_on_error "Fatal: Specifying one or more locdrop tarballs with --trans-files is mandatory."
    fi

    if [[ -z "$P_NOTRANS_DIR" ]]; then
    ccecho "warn" "No notrans-dir was specified. Assuming DC-file directory"
    P_NOTRANS_DIR="$MY_BASEDIR"
    fi

    [[ -z "$P_OUTPUT_DIR" ]] && exit_on_error "Fatal: Specifying an output directory\nwith  --output-dir is mandatory."

    #
    # Extract translated files
    #
    for TAR in $P_TRANS_FILES; do
        if [[ -f $TAR ]]; then
            [[ 1 -eq $DEBUG ]] && echo "Extracting $TAR"
            pushd "$P_OUTPUT_DIR" > /dev/null
            MANIFEST_TRANS=$(tar tfj "$TAR" | grep "$MFT_TRANS_SUFF" 2>/dev/null) || exit_on_error "Could not get manifest of translated files from $TAR"
            ALL_MANIFEST_TRANS_FILES=( "${ALL_MANIFEST_TRANS_FILES[@]}" "$MANIFEST_TRANS" )
            MANIFEST_NOTRANS=$(tar tfj "$TAR" | grep "$MFT_NOTRANS_SUFF" 2>/dev/null) || exit_on_error "Could not get manifest of non-translated files from $TAR"
            ALL_MANIFEST_NOTRANS_FILES=( "${ALL_MANIFEST_NOTRANS_FILES[@]}" "$MANIFEST_NOTRANS" )
            #
            # Extract manifest files found above
            tar xfj "$TAR" "$MANIFEST_TRANS" "$MANIFEST_NOTRANS" 2>/dev/null || exit_on_error "Could not extract manifest files from tarball $TAR"

            #
            # Sometimes it happens that the manifest files contain files that
            # are not part of the tar archive (should not happen, but it did,
            # e.g. with the odg images)
            # This causes tar to fail on extracting (there is no "continue on
            # error) with tar. We rather want to print a warning and continue.
            # Therefore we need to generate appropriate lists
            #
            FILES_IN_TAR=$(tar tfj "$TAR" | sort -u)

            FILES_TRANS_IN_MANIFEST=$(cat "$MANIFEST_TRANS" | awk NF | tr ' ' '\n' | sort -u)

            FILES_MANIFEST_ONLY=$(comm -1 -3 <(echo -e "$FILES_IN_TAR") <(echo -e "$FILES_TRANS_IN_MANIFEST"))
            [[ -n $FILES_MANIFEST_ONLY ]] && ccecho "warn" "Warning: The following files from the manifest are not part of the tarball:\n$FILES_MANIFEST_ONLY"
            FILES_TRANS_EXTRACT="$(echo $FILES_TRANS_IN_MANIFEST)"
            for WRONG in $FILES_MANIFEST_ONLY; do
                FILES_TRANS_EXTRACT="${FILES_TRANS_EXTRACT/$WRONG/}"
            done
            [[ 1 -eq $DEBUG ]] && echo "Running: tar xfj \"$TAR\" $FILES_TRANS_EXTRACT"
            tar xfj "$TAR" $FILES_TRANS_EXTRACT 2>/dev/null || exit_on_error "Could not extract translated files from tarball $TAR"
            popd >/dev/null
        else
            exit_on_error "Fatal: $TAR does not exist"
        fi
    done

    pushd "$P_OUTPUT_DIR" > /dev/null

    #
    # Run optipng on images/src/png if --optipng was specified
    #
    which optipng >/dev/null 2>&1 || NO_OPTIPNG="1"
    which exiftool >/dev/null 2>&1 || NO_EXIFTOOL="1"

    if [[ -z $NO_OPTIPNG && -z $NO_EXIFTOOL ]]; then
        if [[ -d images/src/png && 1 -eq $OPTIPNG ]]; then
            local j=0
            for IMG in images/src/png/*.png; do
                if [[ -z "$(exiftool -Comment $IMG | grep optipng)" ]]; then
                    let "j += 1"
                    optipng -o2 $IMG >/dev/null 2>&1
                    exiftool -Comment=optipng -overwrite_original -P $IMG >/dev/null
                fi
            done
            if [[ 0 -eq $j ]]; then \
                ccecho "result" "No PNG images needed optimization"
            else
                ccecho "result" "$j PNG images have been optimized."
            fi
        fi
    else
        [[ -n $NO_OPTIPNG ]] && ccecho "error" "Error: Cannot find optipng!"
        [[ -n $NO_EXIFTOOL ]] && ccecho "error" "Error: Cannot find exiftool!"
    fi

    #
    # Now create a complete list of translated/untranslated files
    #
    ALL_TRANS_FILES=$(cat "${ALL_MANIFEST_TRANS_FILES[@]}" | awk NF | tr ' ' '\n' | sort -u)
    ALL_NOTRANS_FILES=$(cat "${ALL_MANIFEST_NOTRANS_FILES[@]}" | awk NF | tr ' ' '\n' | sort -u)

    # get all files unique to the notrans lists (the ones that have not
    # been translated)
    LINK_NOTRANS_FILES=$(comm -1 -3 <(echo -e "$ALL_TRANS_FILES") <(echo -e "$ALL_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of files that have not been translated"

    # Process LINK_NOTRANS_FILES to get the file lists we need
    # the awk statements matches multiple occurrences on a single line
    #
    DCFILE_LIST=$(awk '{for(i=1;i<=NF;++i)if($i~/DC-[^ ]*/)print $i}' <(echo "$LINK_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of DC files"
    NO_DCFILE_LIST=$(awk '{for(i=1;i<=NF;++i)if($i !~ /DC-[^ ]*/)print $i}' <(echo "$LINK_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of images and XML files that have not been 'translated'"

    # Get a list of all xml files, we need to query them for entities
    #
    XML_FILE_LIST=$(awk -v path="${P_NOTRANS_DIR}/" '{for(i=1;i<=NF;++i)if($i~/xml\/.*\.xml/)print path $i}' <(echo "$ALL_TRANS_FILES $ALL_NOTRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of all XML files"

    # Copy remaining DC-files
    #
    echo "Copying DC files"
    for DC in $DCFILE_LIST; do
        if [[ -f ${P_NOTRANS_DIR}/$DC ]]; then
            [[ 1 -eq $DEBUG ]] && echo "Copying ${P_NOTRANS_DIR}/$DATA"
            cp "${P_NOTRANS_DIR}/$DC" .
        else
            ccecho "warn" "DC-file does not exist en-tree: ${P_NOTRANS_DIR}/$DC"
        fi
    done

    # Remove the <dm:docmanager> part from the XML files, we cannot read
    # Chinese bug reports and therefore do not want to encourage users
    # to send them
    #

    # 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"

    #
    # Get a list of all translated xml files
    #
    XML_TRANS_FILE_LIST=$(awk '{for(i=1;i<=NF;++i)if($i~/xml\/.*\.xml/)print $i}' <(echo "$ALL_TRANS_FILES") 2>/dev/null) || exit_on_error "Could not get list of translated XML files"
    #
    # Remove entire docmanager block (with --remove-dm) or at least
    # dm_editurl, since we do not have editable localised content
    #
    for _XML_TRANS_FILE in $XML_TRANS_FILE_LIST; do
        if [[ 1 -eq $P_REMOVEDM ]]; then
            # Remove complete docmanager block
            echo "Removing <dm:docmanager> block"
            $XMLSTARLET ed -S --inplace -N dm="urn:x-suse:ns:docmanager" -d "//dm:docmanager" $_XML_TRANS_FILE
        else
            # Remove editurl part - we only want bugreports for localised
            # content. This is always done.
            echo "Removing <dm:editurl> tag"
            $XMLSTARLET ed -S --inplace -N dm="urn:x-suse:ns:docmanager" -d "//dm:docmanager/dm:editurl"$_XML_TRANS_FILE
        fi
    done

    # Link not translated images and XML files
    #
    echo "Linking xml files and images"
    for DATA in $NO_DCFILE_LIST; do
    if [[ -f ${P_NOTRANS_DIR}/$DATA ]]; then
        DIR="$(dirname "$DATA")"
        if [[ "." = "$DIR" ]]; then
            [[ 1 -eq $DEBUG ]] && echo "Linking ${P_NOTRANS_DIR}/$DATA"
            ln -sf "${P_NOTRANS_DIR}/$DATA"
        else
            [[ -d "$DIR" ]] || mkdir -p "$DIR"
            # the realpath statement makes sure a realtive path is used
            # for the link (also see
            # https://stackoverflow.com/questions/2564634)
            [[ 1 -eq $DEBUG ]] && echo "Linking ${P_NOTRANS_DIR}/$DATA"
            (cd "$DIR" && ln -sf "$(realpath --relative-to="." "${P_NOTRANS_DIR}/$DATA")")
        fi
    else
        ccecho "warn" "Cannot create link to \"en\", file does not exist: ${P_NOTRANS_DIR}/$DATA"
    fi
    done


    # Get entity files from the notrans sources and link to them
    #
    echo "Getting entities"
    ENTITIES="$("${LIBEXEC_DIR}/getentityname.py" ${P_NOTRANS_DIR}/xml/*.xml)"
    for ENT in $ENTITIES; do
        if [[ -f $ENT ]]; then
            [[ 1 -eq $DEBUG ]] && echo "Linking ${P_NOTRANS_DIR}/xml/$ENT"
            (cd xml && ln -sf "$(realpath --relative-to="." "$ENT")")
        else
            ccecho "warn" "Cannot find entity file: $ENT"
        fi
    done

    popd >/dev/null

    ccecho "result" "Successfully created files in\n$P_OUTPUT_DIR"
    exit 0
}

###########################################################################
# HELP
#

function help_output-dir {
    cat <<EOF
    --output-dir=DIRECTORY    Output directory in which to unpack the files
                              from the localization drop. Mandatory.
                              Default: unset
EOF
}
function help_notrans-dir {
    cat <<EOF
    --notrans-dir=DIRECTORY   Relative or absolute path to the directory
                              containing the original (untranslated) sources.
                              Links pointing to this directory are created for
                              all files listed in manifest_notrans.txt.
                              Optional. If not specified, the dir name of the
                              DC file is used.
                              Default: DC file directory
EOF
}
function help_remove-dm {
    cat <<EOF
    --remove-dm               Removes <dm:docmanager> blocks from the
                              translated files.
                              Default: unset
EOF
}
function help_trans-files {
    cat <<EOF
    --trans-files="<LIST>"    Specify one or more tarballs with translated
                              files (space-separated) for a single
                              language.
                              Default: unset
EOF
}
