#!/bin/bash

SHM="/dev/shm/golem"

#Flags:    
VerboseFlag=0 #Used for VerboseMode function
    
    
#Id entification of the device/diagnostics/operation/infrastructure, that call this common functions 
#Striktne volame z dir SHM0 or SHMS, kde to je.
bash_source=${BASH_SOURCE[1]} 
pwd=$PWD #e.g. /golem/Dirigent/Infrastructure/Bt_Ecd
setup=$(basename $PWD) # e.g. Basic
instrument=$(basename $PWD) # e.g. Bt_Ecd
family=$(dirname $PWD|sed 's/\/golem\/Dirigent\///g;s/\/golem\/shm_golem\/ActualShot\///g;s/\/dev\/shm\/golem\/ActualShot\///g;s/\/dev\/shm\/golem\/ActualSession\///g') # e.g. Infrastructure , Casem lepe prosim ...
whoami=$family/$instrument/$setup/$bash_source #e.g. Infrastructure/Bt_Ecd/Basic/Bt_Ecd.sh
whereami=$family/$instrument/$setup/ #e.g. Infrastructure/Bt_Ecd/Basic/

#VerboseMod $instrument
ThisDev=$instrument #backward compatibility  # e.g. Bt_Ecd
diag_id=$instrument #backward compatibility # e.g. Bt_Ecd
setup_id=$setup #backward compatibility # e.g. Basic



# ============ General issues ============
GM="golem@golem"
sshGM="ssh $GM"
XTERM="xterm -T $Dev -e ssh golem@$Dev"
shot_dir="/golem/database/operation/shots"
Tek_mount_path="/home/golem/tektronix_drop"
date_format="+%y-%m-%d %H:%M:%S"
psql_password="export PGPASSWORD=$(cat /golem/production/psql_password)"
#DirigentServer="golem-new" 
DirigentServer="golem" 
SW="/golem/Dirigent"
Sounds=$SW/Management/sound_fx/

# ============ Session issues ============

SHMS="$SHM/ActualSession"
SHML="$SHMS/SessionLogBook"
SHMCLP="$SHM/CommandLineParameters"
SHMTAGS="$SHM/Tags"

# ============ Discharge issues ============
SHM0="$SHM/ActualShot"
SHM0TAGS="$SHM0/Production/Tags"
SHMP="$SHM0/Production/Parameters" #Parameters

# ============ General devices ============
RASPs="RasPi3-c/Bt_Ecd RasPi4-a/Chamber"
Sockets=$SHMS/Infrastructure/Support/Sockets/
RelayBoards=$SHMS/Devices/RelayBoards


#============ WWW stuff: ============
linkiconsize="20px"
icon_size="200x150" 
ScreenShotAllSize="1600,1000"
namesize=100
iconsize=200
PingTimeout=20
DummyDischargeCountDown=2
imgpath="http://golem.fjfi.cvut.cz/_static"
gitlabpath="https://gitlab.com/golem-tokamak/dirigent/-/tree/master"
gitlabicon="<img src=$imgpath/gitlab.png  width='$linkiconsize'/>"
googlephotosicon="<img src=$imgpath/GooglePhotos.png  width='$linkiconsize'/>"
manualicon="<img src=$imgpath/manual.png  width='$linkiconsize'/>"
diricon="<img src=$imgpath/direct.png  width='$linkiconsize'/>";
gnuploticon="<img src=$imgpath/gnuplot.png  width='$linkiconsize'/>";
pythonicon="<img src=$imgpath/python.png  width='$linkiconsize'/>";
resultsicon="<img src=$imgpath/results.png  width='$linkiconsize'/>";
parametersicon="<img src=$imgpath/parameters.png  width='$linkiconsize'/>";
psqlicon="<img src=$imgpath/postgresql.webp  width='$linkiconsize'/>";
underconst="<img src=$imgpath/UnderConstruction.png  width='$linkiconsize'/>";
helpicon="<img src=$imgpath/help.png  width='$linkiconsize'/>";
rightarrowicon="<img src=$imgpath/rightarrow.png  width='10px'/>";
#rightarrowicon="&#9755;"
doubledoticon="<img src=$imgpath/dots-horizontal-double-512.webp  width='$linkiconsize'/>";

#Diagnostics_OnStageWithoutBasicDiagnostics=$(echo $Diagnostics_OnStage|sed 's/BasicDiagnostics\/DetectPlasma//g;s/BasicDiagnostics\/Basic//g')

#echo $Diagnostics_OnStage_Without_Detect
#return


dbpath="http://golem.fjfi.cvut.cz/dbase"



NULL="1>/dev/null"
Everything2NULL="1>/dev/null 2>/dev/null"
ThisEntity=$(basename $PWD)
dirigent_dir="/golem/Dirigent" #to be fixed, sorry


RSYNC="rsync --exclude '.*' --exclude '.*.*.kate-swp' --exclude Depository --exclude '*.ipynb_checkpoints' --exclude '*.ipynb_checkpoints/'"


# Logs layouts:
LogFunctionStart="LogIt Diving into .."
LogFunctionEnd="LogIt Ascending from .."
LogFunctionPassing=""
LogFunctionGoingThrough="LogIt Going through .." 


#Alias definitions.
shopt -s expand_aliases
alias IfDummyThenReturn='if [[ -f $SHM/Production/style ]] && [[ $(<$SHM/Production/style) == "dummy" ]]; then return;fi'
alias IfNoPlasmaThenReturn='if [[ -f $SHM0/Production/Tags/b_plasma-NO ]]; then return;fi'

#============ END OF THE HEAD ============


function VerboseMode ()
{
    if (( $VerboseFlag )); then for i in $1; do echo Verbose mode ${BASH_SOURCE[2]}@$(basename ${BASH_SOURCE[1]}): $i: ${!i};done;fi
}

function Verbose ()
{
    for i in $1; do echo Verbose ${BASH_SOURCE[2]}@$(basename ${BASH_SOURCE[1]}): $i: ${!i};done
}

VerboseMode "bash_source pwd family instrument setup whoami"


# General access to all functions everywhere
# **********************************************************

function BasePath (){
local FullPath=$1
    echo $FullPath|sed 's/\/golem\/Dirigent\///g'
}

function DelayCall(){ 
    shuf -i 0-10|head -1|xargs sleep #Protect Electrical Grid up to 10s
    Call $@
}

function Call(){ 
local where=$1
local what=$2
local param1=$3
local param2=$4
local param3=$5
local param4=$6
local param5=$7
local param6=$8
local param7=$9 #lepe

#local script=$(dirname $where|xargs basename)

    [ -f $S HML/LastCallFunction ] && echo "what@where" >$SHML/LastCallFunction
    VerboseMode "where what param script"
    LogItColor 5 "from $(BasePath $PWD) ${FUNCNAME[1]}: $where $what  $param1 $param2 $param3 $param4 $param5 $param6 $param7 $param8 $param9"
    bash -c "cd $where/;source `basename $where`.sh;$what $param1 $param2 $param3 $param4 $param5 $param6 $param7 $param8 $param9"
    #OLD bash -c "cd $where/;source $script.sh;$what $param1 $param2 $param3 $param4 $param5 $param6 $param7 $param8 $param9"
    #LogItColor 5 "Call Return: $what@$where"

}

function SwitchRelay(){
local TheRelay=$1
local ToState=$2
    bash -c "cd $SW/Devices/RelayBoards;source RelayBoards.sh;$TheRelay $ToState"
}


# Broadcasting things to the ..
# **********************************************************


function Broadcast(){
local base=$1
local where=$2
local what=$3


    LogItColor 10 "**$PWD: $(echo "$what@$where" | tr a-z A-Z) .... START"
    SubmitTokamakState "$what@$where"
    for FamilyFull in $where; do
        for InstrumentSetup in ${!FamilyFull}; do 
            #Name=$(echo $Instrument|xargs dirname|xargs basename)
            #Setup=$(echo $Instrument|xargs basename)
            Instrument=`dirname $InstrumentSetup`
            Family=${FamilyFull%_*}
            VerboseMode "FamilyFull Family Instrument"
            if  grep -Rq "function $what" \
                $base/$Family/$Instrument/`dirname $InstrumentSetup|xargs basename`.sh \
                $base/Commons.sh \
                $base/$Family/$Instrument/Universals.sh \
                $base/$Family/$Instrument/../Universals.sh &> /dev/null 
                #is this function defined for this Instrument?
                then 
                LogItColor 5 "Musician:$Instrument .. START $what"
                (time1=$(date  '+%s');bash -c "
                cd $base/$Family/$Instrument; source `dirname $InstrumentSetup|xargs basename`.sh
                $what "$@"";time2=$(date  '+%s');LogItColor 5 $Instrument .. END $what: $(($time2-$time1)) s;if [ -f "Production/FunctionTimes" ]; then  echo $what@$Instrument: $(($time2-$time1)) s >>Production/FunctionTimes;fi ) &
            fi
        done    
    done
	wait
    LogItColor 3 "**$PWD: $(echo "$what@$where" | tr a-z A-Z) .... END"
}






# Ping* issues
# **********************************************************


function PingAllDevices ()
{
local PingCounter=0
local NPingCounter=0

    LogIt
    for TheDevice in $Devices; do 
        Name=$(echo $TheDevice|xargs dirname|xargs basename)
        Setup=$(echo $TheDevice|xargs basename)
        if [[ $(nslookup $Name) =~ "Name" ]]; then #If it has DNS name 
            timeout $PingTimeout  bash -c "
            while ! timeout 1 ping -c 1 -n $Name.golem &> /dev/null; do   
                printf '%s\n' 'waiting for $Setup @ $Name';
                echo false >/dev/shm/golem/Production/PingStatus
                sleep 1;
            done;
            printf '%s\n'  '$Setup @ $Name is online';
            echo true >/dev/shm/golem/Production/PingStatus" &
            let PingCounter++
        else
            printf '%s\n'  "$Setup @ $Name is not ping device"
            let NPingCounter++
        fi
    done
    wait
    echo ======================== 
    echo We have $PingCounter ping devices and $NPingCounter N/A ping devices
    if $(</dev/shm/golem/Production/PingStatus); then echo OK; true; else echo KO; false; fi
}

function PingAllDevicesNtimes
{
N=$2 #how many times
(for i in $(seq 1 $N); do echo Ping $i/$N; if PingAllDevices; then return; fi;done)
}

    
# Sessions issues
# **********************************************************


function SubmitTokamakState ()
{
local what=$1

    if [[ -d $SHML ]]
        then
            echo -n $what > $SHML/tokamak_state
            echo "$(date '+%H:%M:%S') $SHOT_NO:$what" >> $SHML/tokamak_state_log
        fi
   echo -n $what > /golem/production/tokamak_state

}


function PrepareEnvironment@SHM ()
{
local where=$1
local instrument
local family

LogTheFunctionAction

mkdir -p $where/Production

    for family in $(<$SHM/Production/Ensemble); do 
        echo $family >>$where/Production/families
        for InstrumentSetup in ${!family}; do 
            instrument=`dirname $InstrumentSetup`
            setup=`basename $InstrumentSetup`
            echo $InstrumentSetup >>$where/Production/InstrumentSetups
            echo $instrument >>$where/Production/instruments
            VerboseMode "family InstrumentSetup instrument setup"
            mkdir -p $where/${family%_*}/$instrument
            $RSYNC  -r $SW/${family%_*}/$InstrumentSetup/ $where/${family%_*}/$instrument
            #mv $where/${family%_*}/$instrument/`basename $instrument`.sh $where/${family%_*}/$instrument/`basename $instrument`.sh
            echo In this $family/$instrument dir the **$setup** setup is applied > $where/${family%_*}/$instrument/$setup.SETUP
            echo $setup > $where/${family%_*}/$instrument/setup
            #echo $setup > $where/${family%_*}/$instrument/setup.this
            #echo $instrument > $where/${family%_*}/$instrument/instrument.this
            #echo $InstrumentSetup > $where/${family%_*}/$instrument/InstrumentSetup.this
            $RSYNC  -L $SW/${family%_*}/$instrument/*.* $where/${family%_*}/$instrument/ 2>/dev/null
        done 
    done  
 
}
# rm -rf /home/golem/sandbox/*;source Commons.sh ;PrepareEnvironment@SHM /home/golem/sandbox;ls /home/golem/sandbox/
    
# Common Discharge issues
# **********************************************************    

function  GetReadyTheDischarge () #musi byt dve mezery, aby se to nebralo obecne pri Broadcast
{
    GeneralTableUpdateAtDischargeBeginning
}


function Analysis () # Just in case it is not defined
{
    :
}

function NoAnalysis () # Just in case it is not defined
{
    :
}

function PostDischargeAnalysis() # General, if not specified in the Diagnostics set-up
{
   
    if [[ ! -d DAS_raw_data_dir ]]; then ln -s $BasePath/Devices/`dirname $DAS` DAS_raw_data_dir; fi

   #if [[ $(<$SHM0/Operation/Discharge/Basic/Parameters/analysis) != 'off' ]];
   #if [[ $(<$BasePath/Operation/Dirigent/HigherPower/Parameters/analysis) != 'off' ]]; 
   #then
        Analysis
   #else
   #     NoAnalysis
   #fi

    GenerateDiagWWWs $instrument $setup $DAS $notebook $port $DropBox
}



# Log* functions Colors*
# **********************************************************


LogTheDeviceAction()
{
    LogIt The $(basename $whoami) action on stage with ${FUNCNAME[1]}
}

LogTheFunctionAction()
{
    LogIt The Function ${FUNCNAME[1]} on stage ..
}

function TrackIt()
{
:
    #LogIt Tracking .... $1
}


 LogItColor() 
{
    #https://en.wikipedia.org/wiki/ANSI_escape_code#Colors 
    #0 – Black.1 – Red.2 – Green.3 – Yellow.4 – Blue.5 – Magenta.6 (purpur) – Cyan.7 (azur) – White.
    (tput setaf $1
    if [ -e $SHMS/session_date ]; then # check if session has been opened 
        echo  $(date '+%H:%M:%S')\\t  ${FUNCNAME[1]} $2 >> $SHML/LocalLogBook
        printf "$(date +%H:%M:%S) #$(cat $SHM/shot_no) ${FUNCNAME[1]}:\t%s\n" "$2 $3 $4 $5 $6 $7 $8 $9  ${10} ${11} ${12} ${13} ${14} ${15}"|tee -a $SHML/GlobalLogbook 
    else 
        printf "$(date +%H:%M:%S) ${FUNCNAME[1]}:\t%s\n" "$2 $3 $4 $5 $6 $7  $8 $9  ${10} ${11} ${12} ${13} "
	fi
	
    if [ -e $SHM0/ShotLogBook/SessionDate ]; then # check if shot 
        printf "$(date +%H:%M:%S) #$(cat $SHM/shot_no)   ${FUNCNAME[1]}:\t%s\n" "$2 $3 $4 $5 $6 $7  $8 $9  ${10} ${11} ${12} ${13} ">> $SHM0/ShotLogbook 
#	else 
#        printf "$(date +%H:%M:%S) ${FUNCNAME[1]}:\t%s\n" "$1 $2 $3 $4"
	fi	
    tput sgr0)
}


function EchoItColor() 
{
    (tput setaf $1
        echo $2
    tput sgr0)

}

function LogIt() 
{
    if [ -e $SHMS/session_date ]; then # check if session has been opened 
        echo  $(date '+%H:%M:%S')\\t  ${FUNCNAME[1]} $1 >> $SHML/LocalLogBook
        printf "$(date +%H:%M:%S) #$(cat $SHM/shot_no) ${FUNCNAME[1]}:\t%s\n" "$1 $2 $3 $4 $5 $6 $7 $8 $9  ${10} ${11} ${12} ${13} ${14} ${15}" >> $SHML/GlobalLogbook
        printf "$(date +%H:%M:%S) #$(cat $SHM/shot_no) ${FUNCNAME[1]}:\t%s\n" "$1 $2 $3 $4 $5 $6 $7 $8 $9  ${10} ${11} ${12} ${13} ${14} ${15}" >> /dev/shm/golem/SessionStdErrout.log 
    else 
        printf "$(date +%H:%M:%S) ${FUNCNAME[1]}:\t%s\n" "$1 $2 $3 $4 $5 $6 $7  $8 $9  ${10} ${11} ${12} ${13} "
	fi
	
    if [ -d $SHM0 ]; then # check if shot 
        printf "$(date +%H:%M:%S) #$(cat $SHM/shot_no)   ${FUNCNAME[1]}:\t%s\n" "$1 $2 $3 $4 $5 $6 $7  $8 $9  ${10} ${11} ${12} ${13} ">> $SHM0/ShotLogbook 
#	else 
#        printf "$(date +%H:%M:%S) ${FUNCNAME[1]}:\t%s\n" "$1 $2 $3 $4"
	fi	
	
}	

function LogItnewline() 
{
    printf "\n"|tee -a $SHML/GlobalLogbook
}


# Error management
# **********************************************************

function critical_error()
{
    LogIt  "Critical error: $1 ... Stopped"
    if xhost >& /dev/null ; then 
        echo pack [label .error -text {Critical error: $1 ... stopped}]|wish
    fi
}	

# DBs* DB* Database management
# **********************************************************

# e.g.: golem@Dirigent>source Commons.sh ;CreateDiagnosticsTable MHDring_T



function CreateTable () # the function must be executed from appropriate directory
{
    local table_id=${diag_id,,} #tolowercase
    echo $family.$table_id
    $sql_password;
    psql -c 'CREATE TABLE 
                '$family'.'$table_id' (
                    shot_no integer UNIQUE
                    ,session_mission text
                    ,start_timestamp text
                    ,setup_id text
                    ,comment text
                    ,X_discharge_command text
                    )' -q -U golem golem_database
}



function GeneralTableUpdateAtDischargeBeginning () # the function must be executed from appropriate directory
{
    IfDummyThenReturn
    #if (( $DummyFlag )); then return;fi
#    local table_id=${1,,} #tolowercase
    #pwd
    FAMILY=`dirname $PWD|xargs basename`
    DIAG_ID=`basename $PWD`
    local table_id=${FAMILY,,}.${DIAG_ID,,} #tolowercase
    #echo "pSQL update $table_id"



    $psql_password;psql -c "SELECT EXISTS (SELECT FROM $table_id)" -q -U golem -d golem_database &>/dev/null;
    if [ $? -eq 0 ]; then :;  else echo Tahle $table_id neexistuje, pSQL akce zrusena;return; fi

    #return
  
    $psql_password;
    psql -c "INSERT 
                INTO $table_id (
                        shot_no 
                        )
                VALUES (
                    $(<$SHM/shot_no)
                    )" -q -U golem golem_database
    
    if [ ! -f $SHMP/$table_id ]; then return;fi
    local WhatToDo=$(cat $SHMP/$table_id)
    if [[ -f $SHMP/$table_id ]]; then
        psql -c "UPDATE  
                    $table_id 
                 SET 
                    "$WhatToDo" 
                 WHERE shot_no IN(
                    SELECT max(shot_no) FROM $table_id
                            )" -q -U golem golem_database
    fi
    mkdir -p Parameters
    mkdir -p Results
    psql -c "SELECT
                 *
                FROM  
                    $table_id 
                WHERE shot_no IN(
                    SELECT max(shot_no) FROM $table_id
                            )" -x -q -U golem golem_database > AllParameters;
    grep -v RECORD AllParameters|sed 's/| /|/'|awk -F "|" '{print "echo \""$2"\" > Parameters/"$1}' -|bash 1>/dev/null 2>/dev/null
    cat $SHMP/$table_id > Parameters/WholeParametersDefinition
}

function AddColumnToDiagnosticsTable ()
{
    local diag_id=${1,,} #tolowercase

    $psql_password;
    psql -c "ALTER TABLE 
                diagnostics.'$diag_id' 
             ADD COLUMN '$2' '$3';" -q -U golem golem_database
}



#./Dirigent.sh -r DataBaseQuerry shot_no
# TODO: can not it be done the usual way? I.e., psql -c <sql_query>
#
function CurrentShotDataBaseQuerry
{
    $psql_password;
    echo "SELECT
                $1 
            FROM
                operation.discharges
            ORDER BY shot_no  
            DESC LIMIT 1;"|psql -qAt -U golem golem_database 
}


function DataBaseQuerry
{
local QUERRY=$1

    $psql_password;
    Result=`psql -c "$QUERRY" -qAt -U golem golem_database`
    echo "$(date '+%d-%m-%y %H:%M:%S')": $QUERRY --\> $Result>>  /golem/production/querries.psql
    echo $Result

}

function SetCurrentStatus
{
local Quant=$1
local Value=$2
local Table='operation.status'

    DataBaseQuerry "UPDATE $Table SET $Quant=$Value"
}

function GetCurrentStatus
{
local Quant=$1
local Table='operation.status'

    DataBaseQuerry "SELECT $Quant FROM $Table"
}

function SelectDataBaseQuerry #SelectDataBaseQuerry 0 infrastructure.bt_ecd u_cd
{
local ShotNo=$1
local Table=$2
local Quant=$3

    $psql_password;
    psql -c "SELECT $Quant FROM $Table WHERE shot_no=$ShotNo" -qAt -U golem golem_database
}


function UpdateDataBaseQuant #
{
local ShotNo=$1
local Table=$2
local Quant=$3
local Value=$4

    $psql_password;
    psql -c "UPDATE $Table SET $Quant=$Value  WHERE shot_no=$ShotNo" -qAt -U golem golem_database
}

function UpdateDataBaseQuantAtCurrentShot #
{
local ShotNo=`GetCurrentStatus shot_no`
local Table=$1
local Quant=$2
local Value=$3

    #$psql_password;
    DataBaseQuerry "UPDATE $Table SET \"$Quant\"=$Value  WHERE shot_no=$ShotNo"
    #psql -c "UPDATE $Table SET \"$Quant\"=$Value  WHERE shot_no=$ShotNo" -qAt -U golem golem_database
}


# shot_no=$(CurrentShotDataBaseQuerry shot_no) # Nefunguje na RASPs

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function UpdateCurrentShotDataBase
{

    IfDummyThenReturn
    #if (( $DummyFlag )); then return;fi

    $psql_password;
    echo "UPDATE
            operation.discharges 
          SET 
            $1
          WHERE shot_no IN(
             SELECT max(shot_no) FROM operation.discharges
                        )"|psql -q -U golem golem_database 
}

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function UpdateTable
{
table=$1
expression=$2

    IfDummyThenReturn

    #if (( $DummyFlag )); then return;fi

    $psql_password;
    echo "UPDATE 
              $table 
          SET 
              $expression
          WHERE shot_no IN(
              SELECT max(shot_no) FROM $table
                        )"|psql -q -U golem golem_database 
}

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function UpdateTableColumn
{
table=$1
column=$2
expression=$3

    $psql_password;
    echo "UPDATE
              $table
          SET
              $column='$expression' 
          WHERE shot_no IN(
              SELECT max(shot_no) FROM $table
                        )"|psql -q -U golem golem_database 
}

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function DistanceUpdateCurrentShotDataBase
{
    if (( $DummyFlag )); then return;fi
    echo "UPDATE
              operation.discharges
          SET
              $1
          WHERE shot_no IN(
              SELECT max(shot_no) FROM operation.discharges
                        )"|ssh golem "$psql_password;cat - |psql -q -U golem golem_database" 2>/dev/null
}

function RemoteUpdateCurrentSessionDataBase
{
    ssh Dirigent ''$psql_password';psql -c "UPDATE operation.sessions SET '$1' WHERE start_shot_no IN(SELECT max(start_shot_no) FROM operation.sessions)" -q -U golem golem_database'
}

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function InsertCurrentShotDataBase()
{
    #if (( $DummyFlag )); then return;fi
        IfDummyThenReturn
    $psql_password;
    echo "INSERT INTO operation.discharges $1" | psql -q -U golem golem_database
    
}

function InsertCurrentShotDataBaseDischCommand()
{
# specific solution with single quotes:
        IfDummyThenReturn

    $psql_password;
    psql -c "UPDATE  operation.discharges SET \"X_discharge_command\"=E'`cat $SHMP/CommandLine|sed "s/'/\\\\\'/g"`' WHERE shot_no IN(SELECT max(shot_no) FROM operation.discharges)" -q -U golem golem_database
 }   

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function InsertCurrentSessionDataBase()
{
    $psql_password;
    echo "INSERT INTO operation.sessions $1" | psql -q -U golem golem_database
    
}

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function UpdateCurrentSessionDataBase()
{
    $psql_password;
    echo "UPDATE
               operation.sessions
          SET
               $1
          WHERE start_shot_no IN(
               SELECT max(start_shot_no) FROM operation.sessions
                            )"|psql -q -U golem golem_database 
}

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function CurrentSessionDataBaseQuerry()
{
    $psql_password;
    echo "SELECT
                $1
          FROM
                operation.sessions
          ORDER BY
                start_shot_no DESC
         LIMIT 1;"|psql -qAt -U golem golem_database 
}

# TODO: Can it be written in a clearer way? with psql -c <sql_query>?
function WebShotDataBaseQuerry()
{
    WebRec $1: $($psql_password;echo "SELECT $2 FROM shots ORDER BY shot_no  DESC LIMIT 1;"|psql -qAt -U golem golem_database) $3
    #WebRec $1: $(export PGPASSWORD='rale';echo "SELECT $2 FROM shots ORDER BY shot_no  DESC LIMIT 1;"|psql -qAt -U golem golem_database) $3
}

#Problem lowercase etc.:
#psql -q -U golem golem_database -c 'UPDATE shots SET "Ip_mean"=3 WHERE shot_no IN(SELECT max(shot_no) FROM shots)'

#CurrentShotDataBaseQuerry '"D_integral_dose"'

# Time management
# **********************************************************
function mRelax() { sleep 0.1; }

function uRelax() { sleep 0.01; }

function Relax() { sleep 1; }



function CountDown {
local TimeLimit=$1;
local Purpose=$2

    echo Waiting $Purpose .. $TimeLimit s
    for i in $(seq  $TimeLimit -1 1); do echo -ne $i .., ;sleep 1;done 
    echo
}



# Audio
# **********************************************************

mplayer="ssh golem@Chamber.golem cvlc --play-and-exit "
# nutne pridat uzivatele: sudo usermod -a -G audio golem # aby sel i golem
#volume@Discharge: sudo amixer cset numid=1 -- 90 OR sudo alsamixer 
# files now locally at RASP
#sudo scp golem@golem:/golem/tools/sound_fx/*.mp3 /golem/tools/sound_fx/
#ssh pi@discharge 'sudo amixer cset numid=1 -- 90'
#mplayer="ssh golem@192.168.2.117 mplayer"
#mplayer=":"

#https://notevibes.com/cabinet.php
#English - Joanna
#usage: Speaker Problems/there-is-a-problem-with-the-camera-files

function Speaker()
{
local mp3file=$1
    
    echo Doing $mp3file @ Speaker ...
    if [[ $(<$SHM0/Operation/HigherPower/Parameters/voice) == 'off' ]]; then echo -ne Voice off, no sound; return;fi
    #if grep -Rq 'voice="off"' $SHMS/Operation/HigherPower/operation.higherpower ; then echo -ne Voice off, no sound; return;fi
    
    #if [[ -f "$SHM0/Operation/Discharge/Parameters/voice='off'" ]];then return;fi
    scp $SW/Infrastructure/AVIs/Audio/$mp3file.mp3 golem@Chamber.golem:audios/ >/dev/null
    ssh golem@Chamber.golem cvlc --play-and-exit audios/$(basename $mp3file).mp3 1>/dev/null 2>/dev/null 
}

# WWWs
# **********************************************************

function WWWmanagement
{
local what=$1

    bash -c "cd $SHM0/Infrastructure/Homepage; source Homepage.sh; MakeProgressingPage $what";
}

function GenerateDiagWWWs  
{
local instrument=$(basename $PWD)
local setup=$instrument #Hmm opravit
#local DASId=`dirname $3`
local DASId=$(cat $instrument.sh | grep DAS= | cut -d= -f2|sed 's/"//g'|xargs dirname);
local notebook=$4 #obsolete , udelat jinak ...
local port=$(cat Universals.sh | grep port | cut -d= -f2)
local alias=$(cat Universals.sh | grep alias | cut -d= -f2|sed 's/"//g')
local DropBox=$(cat Universals.sh | grep dropbox | cut -d= -f2|sed 's/"//g')
local name=$(cat Universals.sh | grep name | cut -d= -f2|sed 's/"//g');

#local diagpath="http://golem.fjfi.cvut.cz/shots/$SHOT_NO/Diagnostics/$diag_id"
#local diagpath="Diagnostics/$instrument/$setup"
local diagpath="Diagnostics/$instrument"
local devicepath="Devices/$DASId"
cp /golem/Dirigent/Infrastructure/AVIs/Images/Ports/port_$port.jpg .

    rm diagrow.html
    echo "<h3><b>$name</b>&nbsp;Data flow:">>diagrow.html;

    echo "
    <a href=$devicepath/ title="Raw data directory">$diricon</a>    $rightarrowicon">>diagrow.html;

    if [ -e $SHM0/$diagpath/icon-fig.png ]; then
    echo "<a href=$gitlabpath/Diagnostics/$diag_id/$(<setup)/$notebook title="JupyterNotebook$diagpath" target="_blank">$pythonicon</a>
    $rightarrowicon
    <a href=$diagpath/analysis.html title="Analysis$diagpath">$resultsicon</a>$rightarrowicon">>diagrow.html
    fi

        echo "
        <a href=$diagpath/ title="Directory">$diricon</a>
        &nbsp;Documentation:
        <a href=/Composition/Tokamak/diag/$alias/docum.pdf title='Documentation (under construction)'>$manualicon</a>
        <a href=$gitlabpath/$diagpath/$(<setup)/ title="Gitlab4$diagpath" target="_blank">$gitlabicon</a>
     </h3>">>diagrow.html

    if [ -e Parameters/WholeParametersDefinition ];
    then
        echo -n "<a href=$diagpath/Parameters/ title="Parameters">$parametersicon</a>" >>diagrow.html;
        echo -n "Parameters:" >>diagrow.html
        cut -c1-100 Parameters/WholeParametersDefinition >>diagrow.html;
    fi
     echo "<table><tr>

    <!--Port-id start-->

    <td valign=bottom>&nbsp;
    <a href=$diagpath/port_$port.jpg title="Diagnostics placement"><img src=$diagpath/port_$port.jpg width='$iconsize'/></a>
    </td>



    <!--Measurement start-->    
    
    <td valign=bottom>&nbsp;<a href=$diagpath/expsetup.svg><img src=$diagpath/setup.png width='$iconsize' /></a></td>

    <!--Photo gallery start-->

    <td valign=bottom>&nbsp;
    <a href=https://www.dropbox.com/$DropBox title="Photogallery@DropBox"><img src=$diagpath/Overview-thumb.jpg /></a>
    </td>


    <!--Digitatization start-->

 
    <td valign=bottom>&nbsp;<a href=$devicepath/das.html><img src=$devicepath/das.jpg  width='$iconsize'/></a></td>
    <!--<td>
    <a href=$devicepath/das.html title="Manual$devicepath">$manualicon</a><br></br>
    </td>-->

    ">>diagrow.html;
    
    # case one DAS is/is not used for more diagnostics
    if [ -e $SHM0/$diagpath/ScreenShotAll.png ]; then
        echo "
        <td valign=bottom>&nbsp;<a href=$diagpath/ScreenShotAll.png><img src=$diagpath/rawdata.jpg  width='$iconsize'/></a></td>">>diagrow.html;
    else
        echo "
        <td valign=bottom>&nbsp;<a href=$devicepath/ScreenShotAll.png><img src=$devicepath/rawdata.jpg  width='$iconsize'/></a></td>">>diagrow.html;
    fi


    # Analysis OK/KO ?
    if [ -e $SHM0/$diagpath/icon-fig.png ]; then
        echo "<!--Analysis start-->
        
        <td valign=bottom><a href=$diagpath/icon-fig.png><img src=$diagpath/graph.png  width='$iconsize'/></a></td>">>diagrow.html;
    else
    :
#         echo "<td>Analysis N/A</td>">>diagrow.html;
    fi

    echo "</tr></table>" >>diagrow.html;
    
    
    echo "<center><h1>The GOLEM tokamak Basic Diagnostics setup</h1>
    <h2>Photo</h2>
    <img src="/_static/figs/DAS-d_s.jpg" width="25%"></img><br/>
    <h2>Relevant excerpt from the manual</h2>" > setup.html;
    for j in $(seq 0 2); do
        echo "<img src=http://golem.fjfi.cvut.cz/wiki/Education/GMinstructions/extracts/Extracts/Diagnostics/output-$j.jpg width='50%'></img>" >> setup.html;
    done
    
    
}


function Gnuplot_BasicGraph
{
    echo -n "set terminal postscript noenhanced;unset xtics;set size 1,1.05;set origin 0,-0.05;set lmargin 15;set label 'Signal [DAQ units]' at screen 0.05,0.5 center front rotate;set label 'Time [DAQ units]' at screen 0.5,-0.02 center front;set multiplot layout $columncount,1 columnsfirst scale 1.1,1.1 title 'Golem #$(<$SHM/shot_no)';set bmargin -1;set datafile separator ',';" >/tmp/foo; for i in $columns; do echo -n plot \'${diags[$i-$firstcolumn]}'.csv'\' u 1:2 w dots t \'${diags[$i-$firstcolumn]}\'';';done >>/tmp/foo;echo " unset multiplot;" >>/tmp/foo; cat /tmp/foo|gnuplot > ScreenShotAll.eps;convert -rotate 90 ScreenShotAll.eps ScreenShotAll.png
    convert ScreenShotAll.png rawdata.jpg
}

function GenerateAnalysisWWWs  
{

local forwhom=$1
local diagpath="Analysis/$instrument"
#echo Analysis/$instrument|tee diagpath
#local diagpath=Analysis/$(basename $forwhom .sh)
local notebook=$2
      
    echo "<tr>
    <td valign=bottom><a href=$diagpath/><img src=$diagpath/name.png  width='$namesize'/></a></td>
    
    <td valign=bottom><a href=$diagpath/analysis.html><img src=$diagpath/graph.png  width='$iconsize'/></a></td>
    <td>
    <a href=$gitlabpath/$diagpath/$notebook title="JupyterNotebook$diagpath">$pythonicon</a>
    $rightarrowicon
    <a href=$diagpath/analysis.html title="Analysis$diagpath">$resultsicon</a><br></br>
    <a href=$diagpath/ title="Directory">$diricon</a>
    <a href=$dbpath/Diagnostics/$diag_id/ title="Database"><img src=$imgpath/postgresql.webp  width='$linkiconsize'/></a>
    </td></tr>" >diagrow_$instrument.html;
    
    
}






# Others
# **********************************************************

function WaitForFileReady
{
#e.g. WaitForFileReady -file $SHM0/Infrastructure/BiasingElectrode/Parameters/waveform -timeout 10 -step 1
file=$2
timeout=$4
timestep=$6

$LogFunctionGoingThrough

    while ! test -s  $file ;
    do
        if [ "$timeout" == 0 ]; then
        LogItColor 1 "ERROR: Timeout while waiting for the $file file "
        exit 1
    fi
    sleep $timestep
    echo $timeout s to wait for $file files
    ((timeout=timeout-$timestep))
    done
}




function WebRecDas()
{
    echo $1 >> das.html
}

function Flag() # Just for SW tuning
{
    echo Waving from ${FUNCNAME[2]} 
}



function rsyncRASPs()
{
       for Dev in $RASPs;do 
       if timeout 1 ping -c 1 -n $(dirname $Dev).golem &> /dev/null
        then
          echo Doing: $Dev
          cd /golem/Dirigent/Devices/ITs/$Dev; rsync -v *.sh ../../Drivers/Rasp-Commons.sh $SW/Commons.sh $(dirname $Dev):
 #         cd /golem/Dirigent/Devices/ITs/$Dev;source  $Dev.sh;PrepareSessionEnv@SHM;cd $OLDPWD  
        fi
    done
}

function KillAllGMs(){
#./Dirigent.sh -k
    killall -u golem
}



sanb()
{
sleep 3;ls
}

# source Commons.sh ;DischargeEntityTest /golem/Dirigent/Diagnostics/BasicDiagnostics/DetectPlasma.sh

DischargeEntityTest()
{
local SW_dir=/golem/Dirigent
#local Where=$(dirname $1|sed 's/\/golem\/svoboda\/Dirigent\///g')
local Where=${1#*"Dirigent/"}
local Where=${Where#*"ActualShot/"}
local Where=$(dirname $Where)
local What=$(basename $1)


cd $SHM0/$Where
echo pwd: $(pwd)
echo Copying $What $Where ...
echo ====================
cp -v $SW/$Where/*.* .
source $What
echo "Copy DAS $DAS ... (in case)"
echo ====================
cp -v $SW/Devices/$(dirname $DAS)/*.* $SHM0/Devices/$(dirname $DAS)/

GetReadyTheDischarge
TriggerManagement GetReadyTheDischarge
Relax
GeneralDAScommunication $DAS Arming
Arming
Relax
for i in $(seq 1 2); do echo wait $i;sleep 1;done # in NI case
TriggerManagement Trigger
Relax
TriggerManagement SecurePostDischargeState
PostDischargeAnalysis;
ll /dev/shm/golem/ActualShot/Devices/$(dirname $DAS)/; 
ll

cd $OLDPWD
echo pwd: $(pwd)
}

#including ".sh"
# e.g. source Commons.sh ;OpenSessionSomewhere /golem/Dirigent/Devices/Oscilloscopes/RigolMSO5104-a/Stabilization.sh
# e.g. source Commons.sh ;OpenSessionSomewhere /golem/Dirigent/Devices/Oscilloscopes/TektrMSO56-a/BasicDiagnostics.sh 
# e.g. source Commons.sh ;OpenSessionSomewhere /golem/Dirigent/Devices/Oscilloscopes/TektrMSO58-a/21_RunAways_JCetal.sh 
OpenSessionSomewhere()
{
local SW_dir=/golem/Dirigent
local Where=${1#*"Dirigent/"}
local Where=${Where#*"ActualShot/"}
local Where=$(dirname $Where)
local What=$(basename $1)
#local Where=$(dirname $1|sed 's/\/golem\/svoboda\/Dirigent\///g')
#local What=$(basename $1)

echo $Where
echo $What
#return

cd $Where
source $What;OpenSession;

cd $OLDPWD

}

#cp /golem/Dirigent/Commons.sh .;source Commons.sh ;PostDischargeAnalysisTest file:///golem/shm_golem/ActualShot/Diagnostics/BasicDiagnostics4TrainCourses/StandardDAS-b.sh

PostDischargeAnalysisTest()
{
local SW_dir=/golem/Dirigent
local Where=${1#*"Dirigent/"}
local Where=${Where#*"ActualShot/"}
local Where=$(dirname $Where)
local What=$(basename $1)

cd $SHM0/$Where
echo pwd: $(pwd)
echo Copying $What $Where ...
echo ====================
cp -v -r $SW/$Where/* .
source $What

PostDischargeAnalysis;
ll

cd $OLDPWD
#echo pwd: $(pwd)
}


#e.g. source Commons.sh ;AnalysisReconstruction Diagnostics/PetiProbe/21_PetiProbe_KHetal.sh 35468

function AnalysisReconstruction()
{
    cd $SW

    local SW_dir=/golem/Dirigent
    local What=$1
    local shot_no=$2
    
    local PureWhat=${What#*"Dirigent/"}
    echo $PureWhat
    
    cd /golem/database/operation/shots/$shot_no/$(dirname $PureWhat)
    echo cd /golem/database/operation/shots/$shot_no/$(dirname $PureWhat)
    cp -r $SW/$(dirname $PureWhat)/* .
    source $(basename $PureWhat); Analysis
    
    cd $SW




}


#============ Tools ============

#cd /golem/database/operation/shots/$(cat /golem/database/operation/shots/0/shot_no)/Devices/Oscilloscopes/RigolMSO5104-a/;source Stabilization.sh ;GetOscScreenShot ;ll

# @/dev/shm/golem/ActualSession
#for i in `find . -name  driver.sh`; do echo $i;cd `dirname $i`; echo $PWD;source driver.sh;cd $OLDPWD;done
