#!/bin/bash
set -a
shopt -s extglob 
shopt -s nullglob

USAGE="USAGE: ${0##*/} [options] INSTALL-DIR
For Freetown version (4.2.x)
install a TWiki distrib into the directory INSTALL-DIR
This script must be called from a working dir of CVS or SVN repository
exemple: ./utils/twiki-deploy-local -s wiki.ilog.fr -u / /www/wiki
options:
   -s server-name   defaults to `uname -n`.`dnsdomainname`
   -i               force rebuild of config files
   -u url-dir       the base URL of the wiki will be http://server-name/url-dir
		    defaults to the last component of INSTALL-DIR
   -e admin_email   email admin. defaults to $USER@`dnsdomainname`
   -d distrib       a directory with 2 subdirectories: 
		    MAIN the TWiki official distribution
		    twikiplugins the MAIN/twikiplugins mirror of the twiki SVN
		    It can be  a directory or a string XXX if you have 
		    a directory ~/.twiki_XXX_dist
-s, -u, -e are only needed on first invocation or with -i
the PATH is set to /bin:/usr/bin, and /usr/local/bin-safe if it exists
"
# -r (remote) is an internal flag to tell we are called via twiki-deploy-remote
# TODO:
#   check that we can use configure (give the password)
edit='ed -s'

############################################################ Utils
trace   () { echo "== $*"; tracein=false;}
tracem  () { echo "   -- $*"; tracein=false;}
tracem2 () { echo "      $*"; tracein=false;}
tracen () { if ! $tracein; then echo -n "  ";fi; echo -n " $*"; tracein=true;}
tracend () { if $tracein;then echo; fi; tracein=false;}
err () { echo "$*"; exit 1; }
rv=`rsync --version`;  rv="${rv%%+( )protocol version*}"; rv="${rv##* }"
rv="${rv//./}"
if let 'rv>264'; then
do_rsynca () { rsync -a --cvs-exclude --omit-dir-times --no-p --no-g --chmod=ugo=rwX "$@"; }
else
do_rsynca () { rsync -a --cvs-exclude "$@"; }
fi

########################################################### Options
host=`uname -n`.`dnsdomainname`
admin_email="$USER@`dnsdomainname`"
unset url_dir # starts with /
unset src dir
is_remote=false
export tracein=false init=false
tfd=${TWIKI_FREETOWN_DIST:-$HOME/.twiki_freetown_dist}

while test -z "${1##-*}" -a -n "$1";do case $1 in
  -s) host="$2";shift;;
  -u) if test -n "$2"; then url_dir="$2"; else url_dir=/; fi; shift;;
  -i) init=true;;
  -e) admin_email="$2";shift;;
  -t) tempdir="$2";shift;; # ignored, relevant only for twiki-deploy-remote
  -r) is_remote=true;;
  -d) dist="$2";shift
      if test -d "$HOME/.twiki_${dist}_dist"
      then tfd="$HOME/.twiki_${dist}_dist"
      elif test -d "$dist"; then tfd="$dist"
      else err "No such dist: $dist"
      fi;;      
  *) echo "Unknown option: $1"; err "$USAGE";;
  esac;shift
done  

if test "$#" != 1; then  
  echo "Error: one argument required, not $# ($@)"; err "$USAGE"; exit 1
fi
dir="${1%%/}"
if test -z "$url_dir"; then
  url_dir="${url_dir:-${dir##*/}}"; url_dir="/${url_dir%%/}"
fi
case "$url_dir" in [^/]*) url_dir=/"$url_dir";; esac
case "$url_dir" in *[^/]) url_dir="$url_dir"/;; esac

# go to the proper twiki dir level
if test ! -e README_FREETOWN_WEBCORE.txt -a ! -e utils/twiki-deploy-local; then
   err "Must be called from a webcore twiki install!"
fi
src="$PWD"

# ensure these dirs exist, even if empty due to CVS problems
mkdir -p local patches plugins utils

if ! mkdir -p "$dir"; then err "Cannot create new dir $dir"; fi

if ! $is_remote; then 
  if ! ./utils/twiki-versions >TWIKI_VERSION; then 
    err `cat TWIKI_VERSION`; rm -f TWIKI_VERSION
  fi
  chmod a+rw TWIKI_VERSION 2>/dev/null
fi

mpv=`cat TWIKI_VERSION`; mv="${mpv% *}"; pv="${mpv##* }"
versions="Using versions: MAIN: $mv twikiplugins_SVN: $pv"
trace Using Versions
tracem MAIN: $mv
tracem twikiplugins_SVN: $pv


############################################################ Installation
# TODO: check that perl has the CPAN modules
#         CGI::Session  Locale::Maketext::Lexicon Time::Local
# and software LaTeX, dvipng, ImageMagick

var_value () {
  local v=`grep "^[ 	]*[#$]TWiki::cfg{$1}" lib/LocalSite.cfg`
  v="${v#*\'}"; v="${v%\';*}"
  echo "$v"
}

cd "$dir"

if test ! -e bin/LocalLib.cfg -o ! -e lib/LocalSite.cfg; then init=true; fi
if $init; then trace INIT mode
  tracem "server-name = -s $host"
  tracem "url-dir     = -u $url_dir"
  tracem "admin-email = -e $admin_email"
else # reuse values from config files 
  host=`var_value DefaultUrlHost`; host="${host#http://}"
  url_dir=`var_value ScriptUrlPath`; url_dir="${url_dir%bin}"
fi

case "$dir" in /*) abs_dir="$dir";; *) abs_dir=`pwd`;; esac
chmod -R a+rwX . 2>/dev/null
if test -d /usr/local/bin-safe; then binsafe='/usr/local/bin-safe:'
else unset binsafe;fi

trace Distrib
if $init; then
  do_rsynca "$tfd/MAIN/." .
else
  do_rsynca '--exclude='{/data,/logs,/pub,/working} "$tfd/MAIN/." .
fi


echo "Installed on `date '+%Y-%m-%d'` by $USER 
$versions" >WIKI_DESCRIPTION
chmod -R a+rwX . 2>/dev/null

#### Local perl configs
if $init; then
trace bin/LocalLib.cfg
cp bin/LocalLib.cfg.txt bin/LocalLib.cfg 
$edit bin/LocalLib.cfg >/dev/null <<EOF
H
/^[\$]twikiLibPath
c
\$twikiLibPath = "$abs_dir/lib";
.
wq
EOF
locallib_adds="\$TWiki::cfg{LocalesDir} = '$abs_dir/locale';
\$TWiki::cfg{Password} = 'gncQP5C3hLFpQ';
\$TWiki::cfg{Site}{FullLang} = 'en-us';
\$TWiki::cfg{Site}{Lang} = 'en';
\$TWiki::cfg{Site}{CharSet} = 'iso-8859-15';
\$TWiki::cfg{Plugins}{WysiwygPlugin}{Enabled} = 1;
\$TWiki::cfg{Plugins}{RenderListPlugin}{Enabled} = 1;"

### Local twiki config, managed by the "configure" script
trace lib/LocalSite.cfg
cp lib/TWiki.spec lib/LocalSite.cfg
chmod a+rw lib/LocalSite.cfg

$edit lib/LocalSite.cfg  >/dev/null <<EOF
H
/^\(# \)\?[\$]TWiki::cfg{DefaultUrlHost}
c
\$TWiki::cfg{DefaultUrlHost} = 'http://$host';
.
/^\(# \)\?[\$]TWiki::cfg{ScriptUrlPath}
c
\$TWiki::cfg{ScriptUrlPath} = '${url_dir}bin';
.
/^\(# \)\?[\$]TWiki::cfg{PubUrlPath}
c
\$TWiki::cfg{PubUrlPath} = '${url_dir}pub';
.
/^\(# \)\?[\$]TWiki::cfg{PubDir}
c
\$TWiki::cfg{PubDir} = '$abs_dir/pub';
.
/^\(# \)\?[\$]TWiki::cfg{TemplateDir}
c
\$TWiki::cfg{TemplateDir} = '$abs_dir/templates';
.
/^\(# \)\?[\$]TWiki::cfg{DataDir}
c
\$TWiki::cfg{DataDir} = '$abs_dir/data';
.
/^\(# \)\?[\$]TWiki::cfg{LocalesDir}
c
\$TWiki::cfg{LocalesDir} = '$abs_dir/locale';
.
/^\(# \)\?[\$]TWiki::cfg{WorkingDir}
c
\$TWiki::cfg{WorkingDir} = '$abs_dir/working';
.
/^\(# \)\?[\$]TWiki::cfg{SafeEnvPath}
c
\$TWiki::cfg{SafeEnvPath} = '${binsafe}/bin:/usr/bin';
.
/^\(# \)\?[\$]TWiki::cfg{INCLUDE}{AllowURLs}
c
\$TWiki::cfg{INCLUDE}{AllowURLs} = \$TRUE;
.
1
/^\(# \)\?[\$]TWiki::cfg{LoginManager}
c
\$TWiki::cfg{LoginManager} = 'TWiki::Client::TemplateLogin';
.
1
/^\(# \)\?[\$]TWiki::cfg{WebMasterEmail}
c
\$TWiki::cfg{WebMasterEmail} = '$admin_email';
.
wq
EOF

mkdir -p "$abs_dir/tmp"
echo 'Deny from all' >"$abs_dir/tmp"/.htaccess
chmod -R a+rwX 2>/dev/null "$abs_dir/tmp"

trace bin/.htaccess 
cp bin/.htaccess.txt bin/.htaccess 
$edit bin/.htaccess >/dev/null <<EOF
H
1,\$s|{DataDir}|$abs_dir/data|g
1,\$s|401 {ScriptUrlPath}|401 $url_dir/bin|g
1,\$s|{ScriptUrlPath}|http://$host$url_dir/bin|g
1,\$s|{Administrators}|webcore|g
\$a
.
/Allow from 127.0.0.1
a
        Allow from *
.
1
/<FilesMatch \"configure
.,/<[/]FilesMatch/s/^/# /
wq
EOF

fi # $init

#### Plugins
# dirs in plugins/
# this code can call the plugin function
# exemple: plugin $plugin (which is the default if file is empty)
# already there in distrib: 
#    SpreadSheetPlugin CommentPlugin EditTablePlugin InterwikiPlugin 
#    PreferencesPlugin SlideShowPlugin SmiliesPlugin TablePlugin
# and contribs: JSCalendarContrib MailerContrib TipsContrib TwistyContrib 
# TODO:
# config of http://twiki.org/cgi-bin/view/Plugins/MathModePlugin#Plugin_Installation_Instructions
trace Plugins

# $1=plugin-name $2=plugin-dir
# we suppose plugin dirs are empty if they do not have a data/ subdir
plugin () {
  local both_empty=true
  tracem "$1"
  if test -d "$tfd/twikiplugins/$1"; then 
    chmod -R a+rwX "$tfd/twikiplugins/$1" 2>/dev/null
    do_rsynca "$tfd/twikiplugins/$1/." .
    if test -d "$tfd/twikiplugins/$1/data"; then both_empty=false; fi
  fi
  do_rsynca --exclude PREINSTALL --exclude POSTINSTALL "$2"/. .
  if test -d "$2/data"; then both_empty=false; fi
  if $both_empty; then 
    tracem "*** WARNING: $1 not in SVN, please install"
    tracem2 "from http://twiki.org/cgi-bin/view/Plugins/$1"
    tracem2 "into plugins/$1"
  fi
  case "$1" in *Plugin)
  if ! grep -q "TWiki::cfg{Plugins}{$1}{Enabled}" lib/LocalSite.cfg; then
    tracem "Enabling plugin $1"
$edit lib/LocalSite.cfg >/dev/null <<EOF
H
/^1;
-1
a
\$TWiki::cfg{Plugins}{$1}{Enabled} = 1;
.
wq
EOF
  fi;;
  esac
}

# $1=plugindistdir $2=plugin-dir
plugin_remove () {
  if ! test -d "$tfd/twikiplugins/$1"; then return ;fi
  # remove its files and empty dirs
  ( cd "$tfd/twikiplugins/$1"
    find . -type f | while read f; do rm -f "$f";done
    find . -depth -type d | while read d; do rmdir "$d" 2>/dev/null; done )
  ( cd "$2"
    find . -type f | while read f; do rm -f "$f";done
    find . -depth -type d | while read d; do rmdir "$d" 2>/dev/null; done )
  if grep -q "TWiki::cfg{Plugins}{$1}{Enabled} = 1" lib/LocalSite.cfg; then
    tracem "Disabling plugin $1"
$edit lib/LocalSite.cfg >/dev/null <<EOF
H
/^1;
-1
a
\$TWiki::cfg{Plugins}{$1}{Enabled} = 0;
.
wq
EOF
  fi
}

for i in "$src"/plugins/*;do
  if test -d "$i" -a "${i##*/}" != "CVS"; then 
    plugin="${i##*/}"
    if test -e "$i/REMOVE"; then plugin_remove "$plugin" "$i"
    else
      if test -e "$i/PREINSTALL"; then bash "$i/PREINSTALL" "$i"; fi
      plugin "$plugin" "$i"
      if test -e "$i/POSTINSTALL"; then bash "$i/POSTINSTALL" "$i"; fi
    fi
  fi
done
# CalendarPlugin MathModePlugin NavbarPlugin NewsPlugin SpacedWikiWordPlugin
# TWikiDrawPlugin TocPlugin TreePlugin

#### local overrides
trace Local overrides
do_rsynca "$src/local/." .

#### local patches
trace Patches
for i in "$src"/patches/*/INSTALL;do 
  pn="${i%/INSTALL}"
  tracem "${pn##*/}"
  bash "$i" "${i%/INSTALL}" "$abs_dir"
done

#### perl dependencies
trace Perl CPAN dependencies
egrep -v '(^[ 	]*$|^[ 	]*#)' "$src"/CPAN_DEPENDENCIES.txt | while read i; do 
  echo "require $i;" | if ! perl 2>/dev/null; then 
echo "   ## Requires perl package $i, install with:"
if test -x /usr/bin/aptitude; then
  echo "      sudo aptitude install `wget -q -O - 'http://packages.debian.org/search?searchon=contents&keywords='${i//:://}'.pm&mode=exactfilename&suite=stable&arch=any'|grep 'href="/etch/.*perl'|sed -e 's/.*">//' -e s'/<.*//'`"
else echo "      sudo cpan -i $i"
fi
fi;done

############################################################ Wrapup
chmod -R a+rwX . 2>/dev/null
echo '=================================================================='
echo "Wiki ready at $host${url_dir}bin/view"
echo "Configure at $host${url_dir}bin/configure"
