#!/bin/bash

if [ -z "$SEISCOMP_ROOT" ]; then
    echo "SEISCOMP_ROOT is not defined"
    exit 1
fi

pkgname="acquisition"
PKGROOT="$SEISCOMP_ROOT/$pkgname"

export PATH="$PKGROOT/bin:$PATH"

if ! cd "$PKGROOT"; then
    echo "Cannot change directory to $PKGROOT"
    exit 1
fi

if [ ! -r "$SEISCOMP_ROOT/lib/env.sh" ]; then
    echo "Cannot read $SEISCOMP_ROOT/lib/env.sh"
    exit 1
fi

source "$SEISCOMP_ROOT/lib/env.sh"

if [ ! -r "$SEISCOMP_ROOT/lib/keyutils.sh" ]; then
    echo "Cannot read $SEISCOMP_ROOT/lib/keyutils.sh"
    exit 1
fi

source "$SEISCOMP_ROOT/lib/keyutils.sh"

global_cfg="templates/global.cfg"
if [ ! -r "$global_cfg" ]; then
    echo "Cannot read $PKGROOT/$global_cfg!"
    exit 1
fi

station_cfg="templates/station.cfg"
if [ ! -r "$station_cfg" ]; then
    echo "Cannot read $PKGROOT/$station_cfg!"
    exit 1
fi

tmpkey_cfg="templates/tmpkey.cfg"
if [ ! -r "$tmpkey_cfg" ]; then
    echo "Cannot read $PKGROOT/$tmpkey_cfg!"
    exit 1
fi

VERSION="2.5"
KEY_VERSION="2.5"

_init_keys() {
    mkdir -p key

    SEEDLINK="yes"
    DIGISERV="no"
    SLARCHIVE="yes"
    UDPBASE="5500"
    SOURCE=""
    SOURCE_DESC=""
    SOURCE_ATTR=""
    SOURCE_MSG=""
    SRCADDR=""
    SRCPORT=""
    SPROC=""
    SLOT=""
    UDPPORT="auto"
    COMPORT=""
    COMPORT2=""
    BAUDRATE=""
    BAUDRATE2=""
    TERMPORT=""
    SERIAL=""
    AUTH=""
    DIAL="no"
    DIAL_UPTIME="900"
    DIAL_SCHEDULE="0,30 * * * *"
    SELECTORS=""
    TRIG="no"
    ARCH_SELECTORS=""
    ARCH_KEEP="30"
}

_edit_globals() {
    _init_keys

    if [ -f "$SEISCOMP_ROOT/key/global" ]; then
        source "$SEISCOMP_ROOT/key/global"
    fi

    if [ -f "key/global" ]; then
        source key/global
    fi

    if [ "$ADVANCED" = yes ]; then
        AskYN SEEDLINK "Enable SeedLink" "$SEEDLINK"

        if [ "$SEEDLINK" = yes ]; then
            AskYN DIGISERV "Enable Digiserv (required for triggering)" "$DIGISERV"
            
            clients_digiserv="yes"
            if [ "$LOCALSOURCE" != digiserv ]; then
                clients_digiserv="no"
            fi
            
            if [ "$DIGISERV" = yes ]; then
                AskYN clients_digiserv "Connect local clients to Digiserv instead of SeedLink" "$clients_digiserv"
            fi

            LOCALSOURCE=seedlink
            if [ "$clients_digiserv" = yes ]; then
                LOCALSOURCE=digiserv
            fi
        else
            DIGISERV="no"
            LOCALSOURCE=remote
        fi

        Ask SLARCHIVE "Enable slarchive" "$SLARCHIVE"
        Ask UDPBASE "First local UDP port (Q330)" "$UDPBASE"
    else
        SEEDLINK="yes"
        DIGISERV="no"
        LOCALSOURCE=seedlink
    fi
    
    OutputKeys $global_cfg >key/global
}

_select_source() {
    if [ "$(echo templates/source/*)" = "templates/source/*" ]; then
        echo "Cannot find datasource definitions"
        exit 1
    fi
        
    n=0
    cursrc="$SOURCE"
    selsrc=0
    echo
    for s in templates/source/[0-9]*; do
        src[n]="${s##*/}"
        if [ "$cursrc" = "$(echo ${src[n]} | sed -e 's/^[0-9]*_//')" ]; then
            selsrc="$n"
        fi

        (
            source "$s/key"
            if [ $n -le 9 ]; then
                echo " $n) $SOURCE_DESC"
            else
                echo "$n) $SOURCE_DESC"
            fi
        )

        n=$((n+1))
    done

    Ask selsrc "Data source" "$selsrc"
    SOURCE="$(echo "${src[$((selsrc))]}" | sed -e 's/^[0-9]*_//')"
    srcdir="templates/source/${src[$((selsrc))]}"
    source "$srcdir/key"
    echo "Selected $SOURCE_DESC"
}        
    
_edit_keys() {
    _init_keys

    if [ ! -f "$SEISCOMP_ROOT/key/global" ]; then
        echo "Cannot find $SEISCOMP_ROOT/key/global"
        return
    fi

    source "$SEISCOMP_ROOT/key/global"
    
    if [ ! -f "key/global" ]; then
        echo "Cannot find $PKGROOT/key/global"
        return
    fi

    source "key/global"

    if [ -f "$keyfile" ]; then
        source "$keyfile"
    fi

    prevsrc="$SOURCE"
    
    if [ "$SEEDLINK" = yes ]; then
        _select_source

        if [ "$prevsrc" = "$SOURCE" -a -f "$keyfile" ]; then
            source "$keyfile"
        fi
    
        if echo $SOURCE_ATTR | grep -q "\<chain\>"; then
            Ask SRCADDR "IP address or hostname" "$SRCADDR"
            Ask SRCPORT "TCP port" "$SRCPORT"

            seedlink_mode=0
            if [ "$DIAL" = yes ]; then
                seedlink_mode=1
            fi
            
            echo
            echo "0) Real-time"
            echo "1) Dial-up"
            Ask seedlink_mode "SeedLink mode" "$seedlink_mode"

            if [ "$seedlnk_mode" = 1 ]; then
                DIAL="yes"
                Ask DIAL_SCHEDULE "Dial-up schedule" "$DIAL_SCHEDULE"
                Ask DIAL_UPTIME "Uptime" "$DIAL_UPTIME"
            else
                DIAL="no"
            fi

            Ask SELECTORS "Stream selectors" "$SELECTORS"
        
        elif echo $SOURCE_ATTR | grep -q "\<q330\>"; then
            Ask SRCADDR "IP address of Q330" "$SRCADDR"
            Ask SRCPORT "Base UDP port of Q330" "$SRCPORT"
            Ask SLOT "Q330 dataport (1-4)" "$SLOT"
            Ask SERIAL "Q330 serial number" "$SERIAL"
            Ask AUTH "Q330 auth code" "$AUTH"
            Ask UDPPORT "Base UDP port on the SeisComP" "$UDPPORT"

        elif echo $SOURCE_ATTR | grep -q "\<reftek\>"; then
            Ask SRCADDR "IP address or hostname of RTPD" "$SRCADDR"
            Ask SRCPORT "TCP port of RTPD" "$SRCPORT"
            Ask UNIT "Unit ID" "$UNIT"
            UNIT="$(echo $UNIT | tr '[:lower:]' '[:upper:]')"

        elif echo $SOURCE_ATTR | grep -q "\<tcp\>"; then
            Ask SRCADDR "IP address or hostname" "$SRCADDR"
            Ask SRCPORT "TCP port" "$SRCPORT"
            
        elif echo $SOURCE_ATTR | grep -q "\<udp\>"; then
            Ask SRCPORT "Local UDP port" "$SRCPORT"
        
        elif echo $SOURCE_ATTR | grep -q "\<serial\>"; then
            Ask COMPORT "Data port of digitizer" "${COMPORT}"
            Ask BAUDRATE "Baud rate of digitizer" "${BAUDRATE}"
        fi

        if echo $SOURCE_ATTR | grep -q "\<terminal\>"; then
            Ask TERMPORT "Terminal port" "/dev/terminal"
        fi

        if echo $SOURCE_ATTR | grep -q "\<serialws\>"; then
            Ask COMPORT2 "Data port of weather station" "${COMPORT2}"
            Ask BAUDRATE2 "Baud rate of weather station" "${BAUDRATE2}"
        fi

        if [ ! -z "$SOURCE_MSG" ]; then
            echo
            echo -e "$SOURCE_MSG"
            echo
        fi
        
        if echo $SOURCE_ATTR | grep -q "\<raw\>"; then
            Ask SPROC "Stream processing scheme" "$SPROC"
            echo
            echo "Make sure that your actual digitizer/DAS setup matches the stream"
            echo "processing scheme \"$SPROC\" in streams.xml!"
            echo
        fi
        
        if [ "$DIGISERV" = yes ]; then
            AskYN TRIG "Triggered streams" "$TRIG"
            if [ "$TRIG" = yes ]; then
                echo
                echo "Make sure that autopick is enabled!"
                echo "By default HH* and HN* streams are triggered. This can be changed in"
                echo "$srcdir/chain_digiserv_station_trig.tpl"
                echo "Note that triggered streams are independent of the stream which is"
                echo "used for detection by autopick."
                echo
            fi
        fi
    else
        SOURCE=""
        Ask SRCADDR "IP address or hostname" "$SRCADDR"
        Ask SRCPORT "TCP port" "$SRCPORT"
    fi

    if [ "$SLARCHIVE" = yes ]; then
        if [ "$ADVANCED" = yes ]; then
            Ask ARCH_SELECTORS "Archive selectors" "$ARCH_SELECTORS"
        fi

        Ask ARCH_KEEP "Number of days to keep archived data" "$ARCH_KEEP"
    fi

    OutputKeys $station_cfg >$keyfile
}

_get_keys() {
    pkg="$1"
    profile="$(echo -n "$PACKAGES" | sed -e "s/.*\<$pkg\>\(:\([^ ]*\)\)\?.*/\2/")"
    
    if [ -z "$profile" ]; then
        keyfile="$SEISCOMP_ROOT/$pkg/key/station_${NET}_${STATION}"
    else
        keyfile="$SEISCOMP_ROOT/$pkg/key/profile_$profile"
    fi

    if [ -f "$keyfile" ]; then
        source "$keyfile"
        return 0
    fi

    return 1
}

_get_source() {
    SOURCE_ATTR=""
    srcdir=""
    for s in templates/source/[0-9]*$SOURCE; do
        src="$(echo "${s##*/}" | sed -e 's/^[0-9]*_//')"
        if [ "$src" = "$SOURCE" ]; then
            SOURCE_ATTR="$( (source "$s"/key; echo $SOURCE_ATTR) )"
            srcdir="$s"
            break
        fi
    done
}

_write_conf() {
    LoadConfig "$global_cfg" "$tmpkey_cfg"

    INSTALL_SPROC="no"
    INSTALL_TRIGGER="no"
    DAEMON_OPT=""

    _init_keys
    
    if [ ! -f "$SEISCOMP_ROOT/key/global" ]; then
        echo "Cannot find $SEISCOMP_ROOT/key/global"
        return
    fi

    source "$SEISCOMP_ROOT/key/global"
    
    if [ ! -f "key/global" ]; then
        echo "Cannot find $PKGROOT/key/global"
        return
    fi

    source "key/global"

    if [ "$SYSLOG" = yes ]; then
        DAEMON_OPT="-D"
    fi
    
    rm -rf config/*
    rm -rf operator/*
    mkdir -p config/store

    nstat=0
    for n in $SEISCOMP_ROOT/key/network_*; do
        if [ "$n" = "key/network_*" ]; then
            echo "No networks defined"
            break
        fi
        
        NET="${n##*_}"
        source $n

        echo "+ network $NET_DESC"
        
        for s in $SEISCOMP_ROOT/key/station_${NET}_*; do
            if [ "$s" = "key/station_${NET}_*" ]; then
                echo "No stations defined for network $NET"
                break
            fi

            STATION="${s##*_}"
            source $s

            echo "  + station $STAT_DESC"

            if echo $PACKAGES | grep -q "\<$pkgname\>"; then
                if ! _get_keys $pkgname; then
                    echo "    - cannot find $keyfile"
                    continue
                fi
            else
                echo "    - $pkgname not enabled for ${NET}_${STATION}"
                continue
            fi

            if [ "$SEEDLINK" = yes -a "$DIGISERV" = yes -a "$TRIG" = yes ]; then
                if echo $PACKAGES | grep -q "\<autopick\>"; then
                    if ! _get_keys autopick; then
                        echo "    - cannot find $keyfile"
                        continue
                    fi
                else
                    echo "    - autopick not enabled for ${NET}_${STATION} - disabling trigger"
                    TRIG="no"
                fi
            fi

            statext=0
            STATID="$STATION"
            while [ -f config/rc_$STATID ]; do
                statext=$((statext+1))
                STATID="${STATION}${statext}"
            done

            if [ "$UDPPORT" = "auto" ]; then
                UDPPORT="$((2 * nstat + UDPBASE))"
            fi
            
            CHAIN_XML="chain.xml"
            if [ "$DIGISERV" = yes ]; then
                CHAIN_XML="chain_digiserv.xml"
            fi    
           
            if [ "$SEEDLINK" = yes ]; then
                if [ -z "$SOURCE" ]; then
                    SOURCE="chain"
                    DIAL="no"
                fi
            
                _get_source

                if [ -z "$srcdir" ]; then
                    echo "    - cannot find data source $SOURCE"
                    continue
                fi
                
                if echo $SOURCE_ATTR | grep -q "\<chain\>"; then
                    if [ "$DIAL" = yes ]; then
                        OutputFile $srcdir/chain_dialup_group.tpl > \
                          config/store/chain_dialup_"$STATID"
                    else
                        OutputFile $srcdir/chain_realtime_station.tpl > \
                          config/store/chain_realtime_"$SRCADDR":"$SRCPORT"_"$STATID"
                    fi

                    OutputFile templates/seedlink_plugin.tpl > config/store/seedlink_plugin_chain
                  
                elif echo $SOURCE_ATTR | grep -q "\<instance_per_station\>"; then
                    OutputFile $srcdir/plugins.ini.tpl > config/store/plugins.ini_$STATID
                    OutputFile $srcdir/seedlink_plugin.tpl > config/store/seedlink_plugin_$STATID

                elif echo $SOURCE_ATTR | grep -q "\<instance_per_address\>"; then
                    ext="$(ls config/store/plugins.ini_${SOURCE}_* 2>/dev/null | wc -w)"
                    PLUGINID="$SOURCE$((ext))"

                    if [ ! -f "config/store/plugins.ini_${SOURCE}_${SRCADDR}:${SRCPORT}" ]; then
                        OutputFile $srcdir/plugins.ini.tpl > config/store/plugins.ini_${SOURCE}_${SRCADDR}:${SRCPORT}
                        OutputFile $srcdir/seedlink_plugin.tpl > config/store/seedlink_plugin_${SOURCE}_${SRCADDR}:${SRCPORT}
                    fi

                else
                    OutputFile $srcdir/plugins.ini.tpl > config/store/plugins.ini_$SOURCE
                    OutputFile $srcdir/seedlink_plugin.tpl > config/store/seedlink_plugin_$SOURCE
                fi

                OutputFile $srcdir/seedlink_station.tpl > config/store/seedlink_station_$STATID

            elif [ ! -z "$SOURCE" ]; then
                _get_source
                if ! echo $SOURCE_ATTR | grep -q "\<chain\>"; then
                    echo "    - seedlink not enabled - cannot use foreign station ${NET}_${STATION}"
                    continue
                fi
            fi

            OutputKeys $tmpkey_cfg >config/store/tmpkey_$STATID
            
            if [ "$SPROC" != none ]; then
                INSTALL_SPROC="yes"
            fi

            if [ "$TRIG" = yes ]; then
                INSTALL_TRIGGER="yes"
            fi
            
            if [ "$LOCALSOURCE" = seedlink ]; then
                SRCADDR=127.0.0.1
                SRCPORT="$SEEDLINK_PORT"
            elif [ "$LOCALSOURCE" = digiserv ]; then
                SRCADDR=127.0.0.1
                SRCPORT="$DIGISERV_PORT"
            fi
    
            if [ "$SLARCHIVE" = yes ]; then
                echo "${NET} ${STATION} ${ARCH_SELECTORS}" >>"config/slarchive_${SRCADDR}_${SRCPORT}"
            fi
            
            OutputFile templates/rc_station.tpl > config/rc_$STATID
        done
    done

    if [ "$SEEDLINK" = yes ]; then
        mkdir -p seedlink

        INI="seedlink"
        CHAIN_XML="chain.xml"
        LOCALPORT="$SEEDLINK_PORT"

        if [ "$DIGISERV" = yes ]; then
            mkdir -p digiserv

            SRCADDR=127.0.0.1
            SRCPORT="$DIGISERV_PORT"
            CHAIN_XML="chain_seedlink.xml"
            OutputFile templates/chain_head.tpl > config/$CHAIN_XML
            OutputFile templates/chain_digiserv_group.tpl >> config/$CHAIN_XML
            OutputFile templates/seedlink_head.tpl > config/${INI}.ini
            OutputFile templates/seedlink_plugin.tpl >> config/${INI}.ini

            if [ "$INSTALL_TRIGGER" = yes ]; then
                OutputFile templates/trigger_head.tpl > config/trigger.ini
            fi

            for k in config/store/tmpkey_*; do
                STATID="${k##*_}"
                source "$k"
                _get_source
                if [ "$TRIG" = yes ]; then
                    OutputFile $srcdir/chain_digiserv_station_trig.tpl >> config/$CHAIN_XML
                    OutputFile templates/trigger_station.tpl >> config/trigger.ini
                else
                    OutputFile $srcdir/chain_digiserv_station.tpl >> config/$CHAIN_XML
                fi

                OutputFile templates/seedlink_station.tpl >> config/${INI}.ini
            done
            
            echo "  </group>" >> config/$CHAIN_XML
            echo "</chain>" >> config/$CHAIN_XML

            if [ "$INSTALL_TRIGGER" = yes ]; then
                FixLines config/$CHAIN_XML TRIG
            else
                RemoveLines config/$CHAIN_XML TRIG
            fi

            FixLines config/$CHAIN_XML SLNK
            RemoveLines config/${INI}.ini SPROC

            INI="digiserv"
            CHAIN_XML="chain_digiserv.xml"
            LOCALPORT="$DIGISERV_PORT"
        fi

        OutputFile templates/chain_head.tpl > config/$CHAIN_XML

        if [ "$(echo config/store/chain_realtime_*)" != "config/store/chain_realtime_*" ]; then
            CHAIN_ADDR_LIST=$(for f in config/store/chain_realtime_*; do
                echo $f | sed -e 's/^config\/store\/chain_realtime_\([^_]*\).*/\1/g'
            done | sort | uniq)

            for addr in $CHAIN_ADDR_LIST; do
                SRCADDR="$(echo $addr | cut -d ':' -f 1)"
                SRCPORT="$(echo $addr | cut -d ':' -f 2)"

                OutputFile templates/chain_realtime_group.tpl >> config/$CHAIN_XML
                cat config/store/chain_realtime_${addr}_* >> config/$CHAIN_XML
                echo "  </group>" >> config/$CHAIN_XML
            done
        fi

        if [ "$(echo config/store/chain_dialup_*)" != "config/store/chain_dialup_*" ]; then
            cat config/store/chain_dialup_* >> config/$CHAIN_XML
        fi

        echo "</chain>" >> config/$CHAIN_XML
        if [ "$DIGISERV" = yes ]; then
            RemoveLines config/$CHAIN_XML SLNK
        else
            FixLines config/$CHAIN_XML SLNK
        fi

        RemoveLines config/$CHAIN_XML TRIG

        OutputFile templates/${INI}_head.tpl > config/${INI}.ini
        cat config/store/seedlink_plugin_* >> config/${INI}.ini
        cat config/store/seedlink_station_* >> config/${INI}.ini

        if [ "$INSTALL_SPROC" = yes ]; then
            FixLines config/${INI}.ini SPROC
        else
            RemoveLines config/${INI}.ini SPROC
        fi
        
        cat config/store/plugins.ini_* > config/plugins.ini 2>/dev/null
    fi

    rm -rf config/store

    mkdir -p log
    mkdir -p operator
    mkdir -p python
    mkdir -p status
    mkdir -p seq-backup

    if [ "$SLARCHIVE" = yes ]; then
        mkdir -p archive
    fi

    OutputFile templates/filters.fir > config/filters.fir
    OutputFile templates/streams.xml > config/streams.xml
    OutputFile templates/scream2sl.map > config/scream2sl.map
    OutputFile templates/win2sl.map > config/win2sl.map
    OutputFile templates/trigger_ext.py.tpl > python/trigger_ext.py
    OutputFile templates/crontab.tpl > operator/crontab

    if [ "$SLARCHIVE" = yes ]; then
        FixLines operator/crontab SLARC
    else
        RemoveLines operator/crontab SLARC
    fi

    OutputFile templates/acq_ctrl.tpl > operator/acq_ctrl

    if [ "$SEEDLINK" = yes ]; then
        if [ "$SYSLOG" = yes ]; then
            FixLines operator/acq_ctrl SLKD
            RemoveLines operator/acq_ctrl SLNK
        else
            FixLines operator/acq_ctrl SLNK
            RemoveLines operator/acq_ctrl SLKD
        fi
    else
        RemoveLines operator/acq_ctrl SLNK
        RemoveLines operator/acq_ctrl SLKD
    fi

    if [ "$DIGISERV" = yes ]; then
        if [ "$SYSLOG" = yes ]; then
            FixLines operator/acq_ctrl DGSD
            RemoveLines operator/acq_ctrl DIGS
        else
            FixLines operator/acq_ctrl DIGS
            RemoveLines operator/acq_ctrl DGSD
        fi
    else
        RemoveLines operator/acq_ctrl DIGS
        RemoveLines operator/acq_ctrl DGSD
    fi

    chmod 755 operator/acq_ctrl

    OutputFile templates/purge_datafiles.tpl >operator/purge_datafiles
    chmod 755 operator/purge_datafiles

    OutputFile templates/backup_seqfiles.tpl >operator/backup_seqfiles
    chmod 755 operator/backup_seqfiles
}

action="$1"
shift

case "$action" in
    start|stop|check)
        operator/acq_ctrl $action
        exit $?
        ;;
    get_attributes)
        echo "globals,profile,station"
        exit 0
        ;;
    edit_globals)
        if [ $# -ne 0 ]; then
            break
        fi
        _edit_globals
        exit 0
        ;;
    edit_profile)
        if [ $# -ne 1 ]; then
            break
        fi
        NET="NET"
        STATION="STN"
        keyfile="key/profile_$1"
        _edit_keys
        exit 0
        ;;
    edit_station)
        if [ $# -ne 2 ]; then
            break
        fi
        NET="$1"
        STATION="$2"
        keyfile="key/station_$1_$2"
        _edit_keys
        exit 0
        ;;
    write_conf)
        _write_conf
        exit 0
        ;;
    print_crontab)
        if [ -f "operator/crontab" ]; then
            cat operator/crontab
        fi
        exit 0
        ;;
esac

echo "Error: $pkgname config hook called with invalid arguments"
exit 1

