#!/bin/sh
#------------------------------------------------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     |
#   \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
#    \\/     M anipulation  |
#-------------------------------------------------------------------------------
# License
#     This file is part of OpenFOAM.
#
#     OpenFOAM is free software: you can redistribute it and/or modify it
#     under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
#     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
#     for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
#
# Script
#     foamNewCase
#
# Description
#     Create a new case from a template for particular applications
#     - requires rsync
#
#------------------------------------------------------------------------------
siteDir=${WM_PROJECT_SITE:-${WM_PROJECT_INST_DIR:-<unknown>}/site}
userDir=$HOME/.OpenFOAM
version=${WM_PROJECT_VERSION:-unknown}
templateDir="appTemplates"

#------------------------------------------------------------------------------
usage() {
    exec 1>&2
    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
    cat<<USAGE

Usage: ${0##*/} [OPTION]
options:
  -app <name>       specify the application to use
  -case <dir>       specify alternative case directory, default is the cwd
  -list             list the applications available
  -version <ver>    specify an alternative version (default: '$WM_PROJECT_VERSION')

clone initial application settings to the specified case from
    $userDir/$templateDir/{$version,}/<APP>
    $siteDir/$templateDir/{$version,}/<APP>

USAGE
    exit 1
}
#------------------------------------------------------------------------------
unset appName caseName listOpt

# parse options
while [ "$#" -gt 0 ]
do
    case "$1" in
    -h | -help)
        usage
        ;;
    -app)
        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
        appName="$2"
        shift 2
        ;;
    -case)
        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
        caseName="$2"
        shift 2
        ;;
    -l | -list)
        listOpt=true
        shift
        ;;
    -v | -ver | -version)
        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
        version="$2"
        shift 2
        ;;
    -*)
        usage "unknown option: '$*'"
        ;;
    *)
        usage "unexpected argument: '$*'"
        ;;
    esac
done

# need rsync, except for when listing
type rsync >/dev/null 2>&1 || [ "$listOpt" = true ] || usage "Error: 'rsync' seems to be missing"


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

[ -n "$version" ] || {
    echo "Error: no -version specified and \$WM_PROJECT_VERSION is not set"
    exit 1
}

#
# find apps in current directory
# considered an app if it has constant/ and system/ directories
#
findApps()
{
    for app in $(/bin/ls -d * 2>/dev/null)
    do
        [ -d "$app/constant" -a -d "$app/system" ] && echo $app
    done
}


appList=$(
    for dir in $userDir/$templateDir $siteDir/$templateDir
    do
        if cd $dir 2>/dev/null
        then
            findApps                              ## generic
            cd $version 2>/dev/null && findApps   ## version-specific
        fi
    done | sort | uniq
)


listApps()
{
    echo
    echo "applications available:"
    for i in $appList
    do
        echo "    $i"
    done
    echo
}


if [ "$listOpt" = true ]
then
    listApps
    exit 0
elif [ "$(echo $appList | wc -w)" -eq 0 ]
then
    echo "Error: no applications available"
    exit 1
elif [ -z "$appName" ]
then
    echo "Error: no -app specified"
    listApps
    exit 1
fi


# get the corresponding srcDir name
srcDir=$(
    for dir in $userDir/$templateDir $siteDir/$templateDir
    do
        if [ -d $dir ]
        then
            for appDir in $dir/$version/$appName $dir/$appName
            do
                if [ -d $appDir -a -d $appDir/constant -a -d $appDir/system ]
                then
                    echo "$appDir"
                    break 2
                fi
            done
        fi
    done
)


[ -d "$srcDir" ] || {
    echo "Error: could not find template for $appName"
    listApps
    exit 1
}


# adjust for caseName as required
if [ -n "$caseName" ]
then
    [ -d "$caseName" ] || mkdir -p "$caseName"
    cd "$caseName" 2>/dev/null || usage "directory does not exist:  '$caseName'"
fi
newDir=$PWD


[ -d "$newDir" -a -w "$newDir" ] || {
    echo "Error: target directory does not exist or is unwritable"
    echo "    $newDir"
    exit 1
}

# add some useful subdirs:
mkdir -p $newDir/postPro


echo "    application   $appName"
echo "    source        $srcDir"
echo "    target        $newDir"

echo "    syncing ..."
# sync updated files only, itemize changes so we know what is going on
rsync -aui $srcDir/ $newDir


#
# reuse or create new FOAM_SETTINGS (useful for queuing systems)
#
if [ -e "$newDir/FOAM_SETTINGS" ]
then
    echo "    retaining     FOAM_SETTINGS"
else
    echo "    creating      FOAM_SETTINGS"
    cat << SETTINGS > "$newDir/FOAM_SETTINGS"
APPLICATION=$appName
FOAM_VERSION=OpenFOAM-$version
SETTINGS
fi

echo Done

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