#----------------------------------*-sh-*--------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     |
#   \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
#    \\/     M anipulation  |
#------------------------------------------------------------------------------
# License
#     This file is part of OpenFOAM, licensed under GNU General Public License
#     <http://www.gnu.org/licenses/>.
#
# Script
#     paraviewFunctions
#
# Description
#     Helper functions for CMake with ParaView.
#     Setup of variables for creating ParaView plugins
#
# Requires
#     ParaView_DIR  (unless system)
#     PV_PLUGIN_PATH
#
# Provides Functions
#     have_pvplugin_support, no_paraview, echo_paraview
#     cmakeVtk, cmakePv
#
# Variables on success
#     HAVE_PVPLUGIN_SUPPORT
#     FOAM_PV_PLUGIN_LIBBIN
#     PARAVIEW_API - the paraview major/minor numbers (eg 5.6)
#     PARAVIEW_INC_DIR
#
# Note
#     The OpenFOAM plugin must be the first in PV_PLUGIN_PATH and have
#     paraview-major.minor encoded in its name.
#
#------------------------------------------------------------------------------
. $WM_PROJECT_DIR/wmake/scripts/sysFunctions # General system functions
. $WM_PROJECT_DIR/wmake/scripts/cmakeFunctions  # Require cmake functions

#------------------------------------------------------------------------------

# Reset variables
no_paraview()
{
    unset HAVE_PVPLUGIN_SUPPORT FOAM_PV_PLUGIN_LIBBIN
    unset PARAVIEW_API PARAVIEW_INC_DIR
    return 0
}


# Report
echo_paraview()
{
    echo "paraview=${HAVE_PVPLUGIN_SUPPORT:-false}"
    echo "root=$ParaView_DIR"
    echo "include=$PARAVIEW_INC_DIR"
    echo "plugin=$FOAM_PV_PLUGIN_LIBBIN"
    echo "api=$PARAVIEW_API"
}


# CMake into objectsDir with VTK_DIR dependency
cmakeVtk()
{
    cmakeVersioned "VTK_DIR=$VTK_DIR" "$1"
}


# CMake into objectsDir with ParaView_DIR dependency
cmakePv()
{
    cmakeVersioned "ParaView_DIR=$ParaView_DIR" "$1"
}

#
# Build library - use sentinel file(s) to handle paraview version changes
#
wmakeLibPv()
{
    local depend="ParaView_DIR=$ParaView_DIR"
    local sentinel

    for libName
    do
        sentinel=$(sameDependency "$depend" $libName) || \
            wclean $libName

        wmake $targetType $libName \
        && echo "$depend" > ${sentinel:-/dev/null}
    done
}


# Test if a ParaView plugin can be built.
# On success, return 0 and export variables
# -> HAVE_PVPLUGIN_SUPPORT, FOAM_PV_PLUGIN_LIBBIN,
#    PARAVIEW_API, PARAVIEW_INC_DIR
#
# There are several prerequisites for building plugins
#
have_pvplugin_support()
{
    local header settings warn pv_api installDir binDir includeDir targetDir
    warn="==> skip paraview-plugin"

    # Trivial check
    command -v cmake > /dev/null 2>&1 || {
        echo "$warn (no cmake)"
        return 1
    }


    # The OpenFOAM plugin must be the first in PV_PLUGIN_PATH
    # and must have the paraview major+minor version encoded in its name!
    # Eg, PV_PLUGIN_PATH="$FOAM_LIBBIN/paraview-5.5"

    # Get the first entry from PV_PLUGIN_PATH=dir1;dir2;...
    targetDir="${PV_PLUGIN_PATH##;}"
    targetDir="${targetDir%%;*}"

    # Extract the paraview major+minor version from the directory name
    # From /path/paraview-5.6 -> 5.6
    pv_api=$(echo "${targetDir##*/}" | \
        sed -n -e 's/^[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p')

    [ -n "$targetDir" ] || {
        echo "$warn (could determine target)"
        echo "    PV_PLUGIN_PATH=${PV_PLUGIN_PATH:-???}"
        return 1
    }

    [ -n "$pv_api" ] || {
        echo "$warn (could determine major.minor version)"
        return 1
    }

    # Header/library names
    header="pqServerManagerModel.h"

    if [ -n "$ParaView_DIR" ]
    then
        # ParaView_DIR defined. Look for include/

        header=$(findFirstFile \
            "$ParaView_DIR/include/paraview-$pv_api/$header" \
            "$ParaView_DIR/include/paraview/$header"
        )

    else
        # No ParaView_DIR defined
        # - use location of 'paraview' to guess an equivalent ParaView_DIR
        # - assume we can use paraview-config

        binDir="$(command -v paraview 2>/dev/null)"
        binDir="${binDir%/*}"       # Eg, /usr/bin/paraview -> /usr/bin
        installDir="${binDir%/*}"   # Eg, /usr/bin -> /usr

        case "$installDir" in
        (/*)    # An absolute path
            includeDir="$installDir/include"  # Eg, /usr -> /usr/include
        ;;
        esac

        header=$(findFirstFile \
            "$(paraview-config --include 2>/dev/null |sed -ne 's/^ *-I//p')/$header"\
            "${includeDir:+$includeDir/paraview-$pv_api/$header}" \
            "${includeDir:+$includeDir/paraview/$header}" \
            /usr/local/include/"paraview-$pv_api/$header" \
            /usr/local/include/paraview/"$header" \
            /usr/include/"paraview-$pv_api/$header" \
            /usr/include/paraview/"$header" \
            )
    fi


    # Header found?
    [ -n "$header" ] || {
        [ -n "$warn" ] && echo "$warn (no header)"
        return 2
    }

    export HAVE_PVPLUGIN_SUPPORT=true
    export FOAM_PV_PLUGIN_LIBBIN="$targetDir"
    export PARAVIEW_API="$pv_api"
    export PARAVIEW_INC_DIR="${header%/*}"      # Basename

    return 0 # success
}


# Force reset of old variables
no_paraview

# Testing
if [ "$1" = "-test" ]
then
    have_pvplugin_support
    echo_paraview
fi

#------------------------------------------------------------------------------
