#!/bin/sh

argHelp()
{
    echo "Projects management script of OpenSCADA mostly designed to call from OpenSCADA but also can be used independently.
The script is mostly software platform specific and relates now for Linux.
openscada-proj list
openscada-proj proc|create|remove|update {ProjName}
 Commands:
  list   - allowed projects list;
  proc   - proceed for copy RO projects to WR, create desktop links, process core dumps;
  create - create new projects or copy RO projects to WR, create desktop links;
  remove - remove project;
  update - update from 0.8.0 LTS;
 Arguments:
  ProjName - project name;
 Environment variables:
  dPrj     - directory of projects OpenSCADA, can be RO;
  dPrjUser - directory of projects OpenSCADA of the user, WR;
  dSysCfg  - directory of system configuration;
  dData    - directory of system data;

openscada-proj backup|backupRestore {ProjName} [{BackupName}]
openscada-proj backupList {ProjName}
 Commands:
  backup - backup the selected project <ProjName> to the name <BackupName>, or to the current date at missing;
  backupRestore - restore the selected project <ProjName> from the pointed backup name <BackupName>, or from the last one at missing;
  backupList	- list the project <ProjName> backups.
 Arguments:
  ProjName   - project name;
  BackupName - the backup archive name.
 Environment variables:
  OSCD_TAR_ComprPrg - TAR compression program, by default gzip;
  OSCD_TAR_Args     - TAR extra arguments, by default \"--exclude=lock --exclude=ARCHIVES\";
  OSCD_BackLim      - Backups limit, by default 10.
";
}

if test $# -lt 1; then argHelp; exit 0; fi

dPrjUser=${dPrjUser:=~/.openscada}
dPrj=${dPrj:=/usr/share/openscada}
dSysCfg=${dSysCfg:=/etc}
dData=${dData:=/usr/share}

case "$1" in
  list)
    if test -d $dPrjUser; then
	echo "=== User projects ==="
	for fit in `ls $dPrjUser`; do
	    if test -d $dPrjUser/$fit && test -f $dPrjUser/$fit/oscada.xml; then echo "$fit"; fi
	done
	echo "=== Common projects ==="
    fi
    for fit in `ls $dPrj`; do
	if test -d $dPrj/$fit && test -f $dSysCfg/oscada_$fit.xml -o -f $dPrj/$fit/oscada.xml; then echo "$fit"; fi
    done
    ;;
  proc|create)
    if test $# -lt 2; then echo "Not enough arguments!"; exit 1; fi
    prjNm=$2
    dPrjRez=$dPrj/$prjNm

    #User projects directory processing
    if test -n "$dPrjUser" -a ! -d $dPrjUser; then mkdir $dPrjUser; fi
    if test ! -d $dPrjRez -o ! -w $dPrjRez && test -n "$dPrjUser" -a -w $dPrjUser; then
	dPrjRez=$dPrjUser/$prjNm
	#if test -d $dPrj/LibsDB -a ! -d $dPrjUser/LibsDB; then cp -R $dPrj/LibsDB $dPrjUser; fi
	# Creating the user LibsDB folder and setting links to the system DB files of the libraries
	mkdir -p $dPrjUser/LibsDB/
	ln -s $dPrj/LibsDB/* $dPrjUser/LibsDB/ || cp $dPrj/LibsDB/* $dPrjUser/LibsDB/

	if test ! -d $dPrjRez -a -d $dPrj/$prjNm; then
	    mkdir -p $dPrjRez
	    cp -R $dPrj/$prjNm/* $dPrjRez;
	    if test ! -e $dPrjRez/oscada.xml; then cp $dSysCfg/oscada_$prjNm.xml $dPrjRez/oscada.xml; fi
	fi
    fi

    #Generic projects directory processing
    if test ! -d $dPrjRez && test $1 = create -o -w $dSysCfg/oscada_$prjNm.xml; then mkdir -p $dPrjRez; fi
    if test -d $dPrjRez; then
	if test ! -e $dPrjRez/oscada.xml -a ! -w $dSysCfg/oscada_$prjNm.xml; then cp $dSysCfg/oscada_start.xml $dPrjRez/oscada.xml; fi
	if test ! -d $dPrjRez/LibsDB -a ! -L $dPrjRez/LibsDB; then ln -s ../LibsDB $dPrjRez/LibsDB; fi
	if test ! -d $dPrjRez/LibsDB -a ! -L $dPrjRez/LibsDB; then cp -R $dPrjRez/../LibsDB $dPrjRez/LibsDB; fi
	if test ! -d $dPrjRez/ARCHIVES/MESS; then mkdir -p $dPrjRez/ARCHIVES/MESS; fi
	if test ! -d $dPrjRez/ARCHIVES/VAL; then mkdir -p $dPrjRez/ARCHIVES/VAL; fi
	if test -n "$(which xdg-user-dir)" && test -n "$(xdg-user-dir DESKTOP)" -a $1 = create; then
	    DESKTOP_DIR="$(xdg-user-dir DESKTOP)"
	    if test -n "$DESKTOP_DIR"  -a ! -f "$DESKTOP_DIR/openscada_$prjNm.desktop"; then
		cp $dData/applications/openscada.desktop "$DESKTOP_DIR/openscada_$prjNm.desktop"
		sed -i "s/Exec=/Exec=env OSCADA_ProjName=$prjNm /" "$DESKTOP_DIR/openscada_$prjNm.desktop"
		sed -i "s/\(^\(Generic\|\)Name\(=\|\\[.*\\]=\).*\)/\1: $prjNm/" "$DESKTOP_DIR/openscada_$prjNm.desktop"
	    fi
	fi
    fi

    #Checking for lost lock at it PID and openscada process in whole, and starting from the user directory
    dPrjRez=$dPrjUser/$prjNm
    if test ! -d $dPrjRez; then dPrjRez=$dPrj/$prjNm; fi

    if test -f $dPrjRez/lock; then
	pid=`cat $dPrjRez/lock | sed -r 's/^0*([0-9]+).*/\1/'`
	if ! ps -A -o "pid cmd" | grep "^ *$pid.*openscada" > /dev/null; then rm $dPrjRez/lock; fi
    fi

    # Core dump files "core[.*]" into work directory process
    if test -n "$(which gdb 2> /dev/null)"; then
	cd $dPrjRez
	for fit in `ls core* 2> /dev/null`; do
	    resultFile="${prjNm}_${fit}_$(date +%F_%H.%M).crash"
	    echo "Core dump process for back trace purchase to the file $resultFile"
	    gdb /usr/bin/openscada --core ${fit} --batch --quiet -ex "thread apply all bt full" -ex "quit" > $resultFile
	    gzip $resultFile
	    rm -f ${fit}
	done
    fi
    ;;
  remove)
    if test $# -lt 2; then echo "Not enough arguments!"; exit 1; fi
    prjNm=$2
    prjDir=

    if test -n "$dPrjUser" -a -d $dPrjUser; then
	for fit in `ls $dPrjUser`; do
	    if test -d $dPrjUser/$fit && test -f $dPrjUser/$fit/oscada.xml && test $fit = $prjNm; then
		prjDir=$dPrjUser/$fit
		break
	    fi
	done
    else
	for fit in `ls $dPrj`; do
	    if test -d $dPrj/$fit && test -f $dSysCfg/oscada_$fit.xml -o -f $dPrj/$fit/oscada.xml && test $fit = $prjNm; then
		prjDir=$dPrj/$fit
		break
	    fi
	done
    fi

    if test "x$prjDir" != "x"; then
	# Removing the backups
	cd $prjDir/..
	for iF in `ls -t ${prjNm}_*.backup 2> /dev/null`; do rm $iF; done

	# Removing the project folder
	rm -r $prjDir

	# Remove the desktop link
	if test -n "$(which xdg-user-dir)" && test -n "$(xdg-user-dir DESKTOP)"; then
	    DESKTOP_DIR="$(xdg-user-dir DESKTOP)"
	    if test -n "$DESKTOP_DIR" -a -f "$DESKTOP_DIR/openscada_$prjNm.desktop"; then
		rm $DESKTOP_DIR/openscada_$prjNm.desktop
	    fi
	fi
    else exit 1;
    fi
    ;;
  backup)
    if test $# -lt 2; then echo "Not enough arguments!"; exit 1; fi
    prjNm=$2
    prjBackNm=${prjNm}_$(date +%F_%H.%M).backup
    if test $# -ge 3; then prjBackNm=${prjNm}_$3.backup; fi
    prjsDir=$dPrj
    if test -n "$dPrjUser" -a -d $dPrjUser/$prjNm; then prjsDir=$dPrjUser; fi
    cd $prjsDir
    if test -d $prjNm; then
	echo "Backuping the project \"$prjNm\" to $prjBackNm"
	OSCD_TAR_ComprPrg=${OSCD_TAR_ComprPrg:=gzip}
	OSCD_TAR_Args=${OSCD_TAR_Args:=--exclude=lock --exclude=ARCHIVES}
	tar -I$OSCD_TAR_ComprPrg $OSCD_TAR_Args -cvf $prjBackNm $prjNm > /dev/null
	ln -f -s $prjBackNm ${prjNm}_last.backup

	#Processing the backup limit
	iBack=0
	OSCD_BackLim=${OSCD_BackLim:=10}
	for iF in `ls -t ${prjNm}_*.backup 2> /dev/null`; do
	    if test -h $iF; then continue; fi
	    if test $iBack -ge $OSCD_BackLim; then
		echo "Removing $iF by the limit $OSCD_BackLim"
		rm $iF
	    fi
	    iBack=$(($iBack + 1))
	done
    else echo "No the project \"$prjNm\" found!"; fi
    ;;
  backupRestore)
    if test $# -lt 2; then echo "Not enough arguments!"; exit 1; fi
    backNm=last
    if test $# -ge 3; then backNm=$3; fi
    prjNm=$2
    prjsDir=$dPrj
    if test -n "$dPrjUser" -a -d $dPrjUser/$prjNm; then prjsDir=$dPrjUser; fi
    cd $prjsDir
    prjBackNm=${prjNm}_$backNm.backup
    if test -d $prjNm -a -f $prjBackNm; then
	if test -f $prjNm/lock; then echo "Stop the project $prjNm before restoring from the backup $prjBackNm"; exit 1; fi
	echo "Restoring the project \"$prjNm\" from the backup $prjBackNm"
	rm -R $prjNm
	tar xvf $prjBackNm > /dev/null
    else echo "No the backup \"$prjBackNm\" found!"; fi
    ;;
  backupList)
    if test $# -lt 1; then echo "Not enough arguments!"; exit 1; fi
    prjNm=$2
    prjsDir=$dPrj
    if test -n "$dPrjUser" -a -d $dPrjUser/$prjNm; then prjsDir=$dPrjUser; fi
    cd $prjsDir
    for iF in `ls -t ${prjNm}_*.backup 2> /dev/null`; do
	if test -h $iF; then continue; fi
	echo $iF | sed -n "/^${prjNm}_\(.*\)\.backup/s//\1/p"
    done
    ;;
  update)
    if test $# -lt 2; then echo "Not enough arguments!"; exit 1; fi
    prjNm=$2
    # OpenSCADA user folder presence
    if test -z "$dPrjUser" -o ! -d $dPrjUser; then exit 1; fi
    # Source directory checking whether it <prjNm> or "DATA"
    if test -d $dPrjUser/$prjNm; then
	if test ! -f $dPrjUser/$prjNm/oscada.xml; then srcDir=$prjNm; fi
    elif test -d $dPrjUser/DATA -o -d $dPrjUser/.openscada_old/DATA; then srcDir=DATA; fi
    if test -z "$srcDir"; then exit 1; fi

    # Saving the old release data to ".openscada_old"
    if test ! -d $dPrjUser/.openscada_old; then
	mkdir $dPrjUser/.openscada_old
	mv $dPrjUser/LibsDB $dPrjUser/ARCHIVES $dPrjUser/DATA $dPrjUser/*.xml $dPrjUser/*.db $dPrjUser/icons $dPrjUser/.openscada_old/
	cp -R $dPrj/LibsDB $dPrjUser/LibsDB
    fi
    # New project folder creating
    if test ! -d $dPrjUser/$prjNm; then
	mkdir $dPrjUser/$prjNm
	cp $dPrjUser/.openscada_old/DATA/* $dPrjUser/$prjNm
    fi
    # Other elements copying
    cp $dSysCfg/oscada_start.xml $dPrjUser/$prjNm/oscada.xml
    if test ! -f $dPrjUser/$prjNm/St.db -a -f $dPrjUser/$prjNm/MainSt.db; then
	mv $dPrjUser/$prjNm/MainSt.db $dPrjUser/$prjNm/St.db
    fi
    cp -R $dPrjUser/.openscada_old/ARCHIVES $dPrjUser/$prjNm
    ln -s ../LibsDB $dPrjUser/$prjNm/LibsDB
    ln -s ./ $dPrjUser/$prjNm/$prjNm
    ;;
  *) argHelp ;;
esac

exit 0
