#!/bin/bash -e
#
# Install one system

if [ "$#" -ne 2 ];then
    echo "Please specify the name of the system to install and the source code directory." >&2
    exit 1
else
    system=$1
    srcdir=$2
fi

MODEL_BUILD_DIR=models/${system}
BUILD_TARGET_DIR=${MODEL_BUILD_DIR}/target/
BUILD_TARGET_BIN_DIR=${BUILD_TARGET_DIR}/bin/
BUILD_INC_DIR=${MODEL_BUILD_DIR}/include
BUILD_CONFIG_DIR=${MODEL_BUILD_DIR}/config/
BUILD_EPICS_DIR=${MODEL_BUILD_DIR}/epics/
BUILD_EPICS_SRC_DIR=${BUILD_EPICS_DIR}/src/
BUILD_EPICS_BUILD_DIR=${BUILD_TARGET_DIR}/${system}epics/
BUILD_INFO_DIR=${BUILD_TARGET_DIR}/build_info/
BUILD_SUCCESS_FILE=${MODEL_BUILD_DIR}/logs/build_success

echo "Path: ${BUILD_SUCCESS_FILE}"

if ! test -e ${BUILD_SUCCESS_FILE}; then
    echo -e "\nERROR: The '$system' model does not appear to have been built, please build it first, before attempting to install.\n" >&2
    exit 1
fi

if [[ -n $(grep 0 ${BUILD_SUCCESS_FILE} ) ]]; then
    echo -e "\nERROR: The last build of the '${system}' model failed, will not attempt to install."
    echo -e "Please fix any errors and rebuild before attempting to install.\n"
    exit 1
fi

site="${SITE}"
ifo="${IFO}"
if [ -z "$site" ] || [ -z "$ifo" ] ; then
    echo "Could not determine site or ifo." >&2
    exit 1
fi
site=${site^^*}
ifo=${ifo^^*}
site_letter=${ifo:0:1}
upper_system=`echo $system | tr a-z A-Z`
targetcpu=`grep TARGET_CPU ${BUILD_INC_DIR}/${system}.h | head -1 | awk '{print $3}'`
cur_date=`date +%y%m%d_%H%M%S`
ligo_group='advligorts'
archive_last_build=true

if [[ -z "${RCG_TARGET}" ]]; then
    echo "The RCG_TARGET env var must be set when trying to install models"
    exit 1
else
    RTCDS=${RCG_TARGET}
fi
TARGET=$RTCDS/target/${system}
TARGET_ARCHIVE_BASE_DIR=$RTCDS/target_archive/${system}
TARGET_ARCHIVE_CUR_VER_DIR=${TARGET_ARCHIVE_BASE_DIR}/${system}_$cur_date
MODEL_IOC_LOG_DIR=$RTCDS/log/${system}/


# If we already have a testpoint.par save the path so we can add the new model we are installing to it
if test -e $RTCDS/target/gds/param/testpoint.par; then
    new_install=false
    testpoint_par_infname=$RTCDS/target/gds/param/testpoint.par
elif test -e $RTCDS/target/gds/param/; then
    echo "WARNING No testpoint.par file found, even though previous install detected."
    testpoint_par_infname=/dev/null
    new_install=false
else
    testpoint_par_infname=/dev/null
    new_install=true
fi
upgrade_install=false

echo "Installing system=$system site=$site ifo=$ifo"
mkdir -p $TARGET
mkdir -p ${MODEL_IOC_LOG_DIR}

#Always create the filter_archive, because the epics process writes to this on startup
if [[ ! -d $RTCDS/chans/filter_archive/$system ]]; then
    mkdir -p $RTCDS/chans/filter_archive/$system
    chmod 775 $RTCDS/chans/filter_archive/$system
fi
##########



if [[ -d ${MODEL_IOC_LOG_DIR} ]]; then 

    if [[ ${new_install} == true ]]; then #Brand new install we need to create a successful_install file
        echo "0" > ${MODEL_IOC_LOG_DIR}/successful_install 
    fi

    if [[ ! -f ${MODEL_IOC_LOG_DIR}/successful_install && ${new_install} == false ]]; then
        # When converting from the old install to this new version, we will
        # interpret no successful_install file being present as actually a
        # successful install from a older version
        echo "WARNING: Creating ${MODEL_IOC_LOG_DIR}/successful_install file because none exists."
        echo "WARNING: This should only happen once when upgrading to RCG 5+"
        echo "0" > ${MODEL_IOC_LOG_DIR}/successful_install
        upgrade_install=true

    fi

    if [[ -n $(grep 1 ${MODEL_IOC_LOG_DIR}/successful_install) || ${upgrade_install} == true ]]  ; then

        echo "Archiving last install..."

        ## Copy the chans/ files into the filter archive
        if test -e $RTCDS/chans/${upper_system}.txt; then
            cp  $RTCDS/chans/${upper_system}.txt $RTCDS/chans/filter_archive/$system/${upper_system}_${cur_date}_install.txt
        fi

        # Copy the target/<model> dir into the archive
        if test -e $TARGET; then
            mkdir -p ${TARGET_ARCHIVE_BASE_DIR}
            mv -f $TARGET $TARGET_ARCHIVE_CUR_VER_DIR 
        fi

        # Back up the old medm screens
        if test -e $RTCDS/medm/${system}; then
            mkdir -p $RTCDS/medm/archive
            cp -RL  $RTCDS/medm/${system} $RTCDS/medm/archive/${system}_${cur_date}
        fi

        # GDS archive
        mkdir -p  $RTCDS/target/gds/param/archive
        if test -e $RTCDS/target/gds/param/testpoint.par; then
            cp -p $RTCDS/target/gds/param/testpoint.par $RTCDS/target/gds/param/archive/testpoint_${cur_date}.par
        fi

        if test -e $RTCDS/target/gds/param/tpchn_${system}.par; then
            mv -f $RTCDS/target/gds/param/tpchn_${system}.par $RTCDS/target/gds/param/archive/tpchn_${system}_${cur_date}.par
        fi


        # DAQ archive
        mkdir -p  $RTCDS/chans/daq/archive/
        if test -e $RTCDS/chans/daq/${upper_system}.ini; then
            mv -f $RTCDS/chans/daq/${upper_system}.ini $RTCDS/chans/daq/archive/${upper_system}_${cur_date}.ini
        fi



    else
        archive_last_build=false
        if [[ ${new_install} == false ]]; then
            echo "WARNING: Skipping previous build archival because the last install FAILED."
        fi
    fi


else
    echo "Skipping previous build archival because there was no previous build."
fi

#Mark install as failed, we will mark as successful at the end of this script
#We need to wait until the check above is done
echo "0" > ${MODEL_IOC_LOG_DIR}/successful_install


##########




##########

echo "Installing channel file..."

# If there is already a channel file for this model and we have an archive version
if test -e $RTCDS/chans/${upper_system}.txt; then

    if test -e $RTCDS/chans/filter_archive/$system/${upper_system}_${cur_date}_install.txt; then
        head -5 ${BUILD_EPICS_SRC_DIR}/config/${ifo}${upper_system}.txt > $RTCDS/chans/${upper_system}.txt
        grep '^# MODULES' ${BUILD_EPICS_SRC_DIR}/config/${ifo}${upper_system}.txt >> $RTCDS/chans/${upper_system}.txt
        tail -n +6 $RTCDS/chans/filter_archive/$system/${upper_system}_${cur_date}_install.txt | grep -v '^# MODULES' >> $RTCDS/chans/${upper_system}.txt
    else
        # When there is no filter archive, the last installed failed, but we still want to combine filter files from the new build and what's installed
        # Solution is to build a tmp file for combination
        head -5 ${BUILD_EPICS_SRC_DIR}/config/${ifo}${upper_system}.txt > $RTCDS/chans/${upper_system}_tmp.txt
        grep '^# MODULES' ${BUILD_EPICS_SRC_DIR}/config/${ifo}${upper_system}.txt >> $RTCDS/chans/${upper_system}_tmp.txt
        tail -n +6 $RTCDS/chans/${upper_system}.txt | grep -v '^# MODULES' >> $RTCDS/chans/${upper_system}_tmp.txt
        cp $RTCDS/chans/${upper_system}_tmp.txt $RTCDS/chans/${upper_system}.txt
        rm $RTCDS/chans/${upper_system}_tmp.txt
    fi
else
    mkdir -p $RTCDS/chans/
    cp -p ${BUILD_EPICS_SRC_DIR}/config/${ifo}${upper_system}.txt  $RTCDS/chans/${upper_system}.txt
fi

# This dir may not be present if we don't have any archives yet
#if test -e $RTCDS/chans/filter_archive/$system/; then
#    chgrp $ligo_group $RTCDS/chans/filter_archive/$system/
#fi


##########

echo "Installing EPICS sequencer..."


mkdir -p $TARGET/{bin,scripts,logs}
chmod 775 $TARGET/logs
mkdir -p $RTCDS/chans/tmp
chmod 775 $RTCDS/chans/tmp
#chgrp $ligo_group $RTCDS/chans/tmp
mkdir -p $TARGET/${system}epics/burt
chmod 775 $TARGET/${system}epics/burt

mkdir -p ${MODEL_IOC_LOG_DIR}
#chgrp $ligo_group ${MODEL_IOC_LOG_DIR}
chmod g+rwx ${MODEL_IOC_LOG_DIR}

## If we had burt files in the old install copy them back over into the new install
if [ -e $RTCDS/target_archive/${system}/${system}_$cur_date/${system}epics/burt ]; then
    cp -pr $RTCDS/target_archive/${system}/${system}_$cur_date/${system}epics/burt $TARGET/${system}epics
fi

cp -pr ${BUILD_EPICS_BUILD_DIR}/* $TARGET/${system}epics #Copy epics process dir to install dir

#If we aren't going to back up the this directory, we need to add write permissions so we can remove it
if [ "$archive_last_build" = false ]  && test -e $TARGET/build_info/ ; then
    chmod -R ug+rw $TARGET/build_info/
    rm -rf $TARGET/build_info/
fi

cp -rf ${BUILD_INFO_DIR} $TARGET
chmod -R a-w $TARGET/build_info

if test -e $TARGET/${system}epics/db/*/autoBurt.req; then
    mv -f $TARGET/${system}epics/db/*/autoBurt.req $TARGET/${system}epics
fi

if [ -n "$(ls -A $TARGET/${system}epics/burt 2>/dev/null)" ]; then #If we have (at least one file in dir)
    for file in "$TARGET/${system}epics/burt"/*
    do
        if [ ! -d "$file" ]; then
            cur_owner="$(stat --format '%U' "$file")" 
            cur_group="$(stat --format '%G' "$file")"
            #if [ "$cur_owner" == "$USER" ]; then
            #    chgrp $ligo_group $file
            #elif [ "$cur_group" != "$ligo_group"  ]; then
            #    echo "Warning $file, does not have $cur_group group ownership, and installer cannot set it."
            #fi
        fi
    done
fi

##########

echo "Installing EPICS screens..."

mkdir -p $RTCDS/medm/${system}
(cd ${BUILD_EPICS_SRC_DIR}/medm; find . -name "*.adl" | xargs -r cp --parents -r -t $RTCDS/medm/${system})
(cd ${BUILD_EPICS_SRC_DIR}/medm; find . -name "*.ui" | xargs -r cp --parents -r -t $RTCDS/medm/${system})

##########

echo "Installing RT components..."

# The whole $TARGET dir was moved into the archive during the archive step

# If we have a new .ko to install
if test -e ${BUILD_TARGET_BIN_DIR}/${system}.ko; then
    cp -fp ${BUILD_TARGET_BIN_DIR}/${system}.ko $TARGET/bin/
fi

# If we have a new userspace build to install
if test -e ${BUILD_TARGET_BIN_DIR}/${system}; then
    cp -fp ${BUILD_TARGET_BIN_DIR}/${system} $TARGET/bin/
fi

# Create userspace startup script if we need one
if test -e $TARGET/bin/${system}; then
    echo  $TARGET/bin/${system} '-m ' ${system} ' >  '$TARGET/logs/log.txt ' 2>& 1 &' > $TARGET/scripts/startup${ifo}usp
    chmod +x $TARGET/scripts/startup${ifo}usp
fi

##########

gds_node=`grep rmid ${BUILD_EPICS_SRC_DIR}/${system}.par | head -1 | sed 's/[^0-9]*\([0-9]*\)/\1/'`
if [ x$gds_node != "x" ]; then #If gds_node is empty this fails

    echo "Installing GDS components..."

    targethost=`grep TARGET_HOST_NAME ${BUILD_INC_DIR}/${system}.h | head -1 | awk '{print $3}'`

    mkdir -p  $RTCDS/target/gds/
    edcu_name=`echo ${upper_system} | sed s/^${ifo}//g`
    edcu_name=${ifo}EDCU_${edcu_name}
    mkdir -p  $RTCDS/target/gds/param/

    ##########

    if [[ $gds_node -lt 256 ]] && test -e ${BUILD_TARGET_BIN_DIR}/${system}.ko; then
        echo "Updating testpoint config file..."
    
        if $srcdir/src/epics/util/updateTestpointPar.py -par_file=${testpoint_par_infname}\
           -gds_node=${gds_node} -site_letter=${site_letter} -system=${system} -host=${targethost}\
           > $RTCDS/target/gds/param/testpoint_tmp.par; then

            cp -p $RTCDS/target/gds/param/testpoint_tmp.par $RTCDS/target/gds/param/testpoint.par
            rm $RTCDS/target/gds/param/testpoint_tmp.par

         else #Keep the last testpoint.par file
             rm $RTCDS/target/gds/param/testpoint_tmp.par
             echo "Error the /src/epics/util/updateTestpointPar.py script failed."
             exit 1
        fi
    else
        echo "Skipping testpoint file update because {${system}} is detected as EPICs only."

    fi
    ##########

    echo "Installing GDS node config file..."

    cp -p ${BUILD_EPICS_SRC_DIR}/${system}.par $RTCDS/target/gds/param/tpchn_${system}.par
    mkdir -p $TARGET/param/
    cp -p ${BUILD_EPICS_SRC_DIR}/${system}.par $TARGET/param/tpchn_${system}.par
    mkdir -p  $RTCDS/chans/adc
    cp -p ${BUILD_EPICS_SRC_DIR}/config/adcListSorted.txt  $RTCDS/chans/adc/${system}_adclist.txt

    #echo "Installing model config files..."
    cp -p ${BUILD_CONFIG_DIR}/* $TARGET/param/


    echo "Installing auto-generated DAQ config file..."

    mkdir -p  $RTCDS/chans/daq
    #Always create daq/archive because the epics process writes to this on startup
    mkdir -p  $RTCDS/chans/daq/archive/
    #if [ -e $RTCDS/chans/daq/archive/ ]; then
        #chgrp $ligo_group $RTCDS/chans/daq/archive/
        #chmod g+rwx  $RTCDS/chans/daq/archive/
    #fi

    cp -p ${BUILD_EPICS_SRC_DIR}/${system}.ini $RTCDS/chans/daq/${upper_system}.ini
    cp $RTCDS/chans/daq/${upper_system}.ini $TARGET/param/${upper_system}.ini
fi

##########

if [ -e $srcdir/src/epics/util/post_build_script.py ]; then
    echo "Running post-build script..."
    $srcdir/src/epics/util/post_build_script.py -q ${system}
    if [ ! -e $TARGET/${system}epics/burt/OBSERVE.snap ]; then 
        ln -s $TARGET/${system}epics/burt/safe.snap $TARGET/${system}epics/burt/OBSERVE.snap
        #chown -h $USER:$ligo_group $TARGET/${system}epics/burt/OBSERVE.snap
        echo "Created new OBSERVE.snap, by symlinking to safe.snap"
    fi
fi

#chgrp $ligo_group $TARGET/${system}epics/burt/
#chgrp $ligo_group $TARGET/${system}epics/burt/safe.snap

echo "1" > ${MODEL_IOC_LOG_DIR}/successful_install
