#! /bin/sh -e

# Licensed under the Apache License, Version 2.0 (the "License"); you
# may not use this file except in compliance with the License. You may
# obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.

basename=`basename "$0"`

staticdir="%localbuilddatadir%"
erlanglibdir="%localerlanglibdir%"
couchversion="%version%"
dbdir="%localstatelibdir%"
viewdir="%localstatelibdir%"
confdir="%localconfdir%"
urifile="%localstaterundir%/couch.uri"
logdir="%localstatelogdir%"

version () {
    cat << EOF
$basename - %package_name% configuration helper %version%

Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

EOF
}

usage()
{
    cat << EOF
Usage: $basename [OPTION]

The $basename command runs the %package_name% configuration helper
script.

Options:

  --erl-libs-dir    Erlang library directory
  --config-dir      configuration directory
  --db-dir          database directory
  --view-dir        view index directory
  --static-dir      static asset directory
  --doc-dir         documentation directory
  --log-dir         log directory
  --uri-file        daemon sockets file 
  --couch-version   version of Apache CouchDB
  --version         version of $basename
  --help            Print usage

If you want to add an option in couch-config or report bugs please do it
at <%bug_uri%>.
EOF
}
  

if [ $# -lt 1 ]; then
    usage
    exit 1
fi


while [ $# -gt 0 ];
do
    arg="$1"
    var=`echo $arg | sed -e 's/^[^=]*=//'`
    
    case "$arg" in
        --erl-libs-dir)
            echo $erlanglibdir
            ;;
        --config-dir)
            echo $confdir
            ;;
        --db-dir)
            echo $dbdir
            ;;
        --view-dir)
            echo $viewdir
            ;;
        --static-dir)
            echo $staticdir
            ;;
        --doc-dir)
            echo $staticdir
            ;;
        --log-dir)
            echo $logdir
            ;;
        --uri-file)
            echo $urifile
            ;;
        --couch-version)
            echo $couchversion
            ;;
        --version)
            version
            exit 0
            ;;
        --help)
            usage
            exit 0
            ;;
        *|-*)
	        echo $basename: ERROR Unknown Option $arg 1>&2
            echo 1>&2
            usage 1>&2
            echo "### $basename: Exitting." 1>&2
            exit 1;
            ;;
    esac
    shift
done

exit 0
