#!/usr/bin/env bash
#
# ionscript
# David Young
# Sep 20, 2008
#
# The program will manage the various configuration files needed to start an
# ion node.  It will take several specified rc files (man ionrc ionsecrc ltprc
# bprc cfdprc ipnrc dtn2rc dtpcrc) and put them into a single
# large configuration file with the appropriate section markers as needed by
# ionstart.sh.
# The program can also perform the opposite function: take a single large
# formatted configuration file, as would be used by ionstart.sh, and split it
# into individual components.
# The program supports the optional TAG for storing more than one configuration
# into the same file (only in the larger file) and also supports appending to
# the larger file, to fully utilize this feature.
# The program also tries it's best to clean out the marker lines when splitting
# a large configuration into a smaller one. NOTE: this will remove any lines
# from the configuration which start with '##'

# the location of the awkscript.
# defining the environment variable AWKSCRIPT before running this script
# will work (for things like make test) before installation
if [[ ! -r "${AWKSCRIPT}" ]] ; then
    SUBFOLDER=$(dirname "${0}")
    # assuming this bash script is installed with the usual binaries from autoconf
    AWKSCRIPT="${SUBFOLDER}/../share/ion/ionstart.awk"
    if [[ ! -r "${AWKSCRIPT}" ]] ; then
        echo
        echo "Didn't find awk script in ${AWKSCRIPT} now searching locally..."
        # assume the bash script is in the same location as the awk script
        AWKSCRIPT="${SUBFOLDER}/ionstart.awk"
        if [[ ! -r "${AWKSCRIPT}" ]] ; then
            echo
            echo "Cannot find the location of the awk script."
            echo "I thought it would be ${AWKSCRIPT} , but nothing is there."
            echo "Set the environment variable AWKSCRIPT or edit me in ${0}"
            exit 1
        fi
    fi
fi

function USAGE {
    echo
    echo    "IONSCRIPT: Interplanetary Overlay Network configuration creation script."
    echo    "USAGE:"
    echo    "   ionscript <-I input | -O output>        [-A] [-t tag]   [-b bprc]"
    echo    "            [-c cfdprc]    [-d dtn2rc]     [-D dtpcrc]     [-i ionrc]      [-l ltprc]"
    echo -n "            [-p ipnrc]     [-s ionsecrc]"
    echo
    echo "	-I input	Specifies file containing the configuration for each"
    echo "			ion administration program. Each section must be"
    echo "			preceded by: ## begin programname tag"
    echo "			and proceeded by: ## end programname tag"
    echo "			If this INPUT option is defined, then the files"
    echo "			defined in -b -c -d -i -l -p -s will be OUTPUT"
    echo "			with the appropriate configuration section."
    echo
    echo "	-O output	Specifies file to contain the configuration for each"
    echo "			ion administration program. Each section will be"
    echo "			preceded by: ## begin programname tag"
    echo "			and proceeded by: ## end programname tag"
    echo "			If this OUTPUT option is defined, then the files"
    echo "			defined in -b -c -d -i -l -p -s will be used"
    echo "			to add an appropriate configuration section to output."
    echo
    echo "	-t tag		Optional tag, used to specify which sections are used"
    echo "			in config file.  If unspecified, sections with no tag"
    echo "			are used."
    echo
    echo "	-A		Specifies if the output files are to be appended to"
    echo "			instead of overwritten."
    echo
    echo "	-b bprc		Specifies file bprc to be used with bpadmin."
    echo "			Default filename is input|output.tag.bprc."
    echo "	-c cfdprc	Specifies file cfdprc to be used with cfdpadmin."
    echo "			Default filename is input|output.tag.cfdprc."
    echo "	-d dtn2rc	Specifies file dtn2rc to be used with dtn2admin."
    echo "			Default filename is input|output.tag.dtn2rc."
    echo "	-D dtpcrc	Specifies file dtpcrc to be used with dtpcadmin."
    echo "			Default filename is input|output.tag.dtpcrc."
    echo "	-i ionrc	Specifies file ionrc to be used with ionadmin."
    echo "			Default filename is input|output.tag.ionrc."
    echo "	-l ltprc	Specifies file ltprc to be used with ltpadmin."
    echo "			Default filename is input|output.tag.ltprc."
    echo "	-p ipnrc	Specifies file ipnrc to be used with ipnadmin."
    echo "			Default filename is input|output.tag.ipnrc."
    echo "	-s ionsecrc	Specifies file ionsecrc to be used with ionsecadmin."
    echo "			Default filename is input|output.tag.ionsecrc."
    echo ""
    echo "  <second>:   optional for -i and -b. Admin program will run these files after initial launch"
    echo "              of non-delayed rc files. If delay is set as 0 explicitly, file will launch"
    echo "              immediately after all non-delayed rc files were executed."
}

# Declare an array to hold multiple ionrc files
declare -a IONRC_FILES=()
declare -a BPRC_FILES=()

# check for all the options
while getopts ":i:d:D:c:p:b:l:I:O:t:s:hA" options; do
    case $options in
        I ) INPUTFILE="${OPTARG}"
            DEFAULTBASEFILE="${OPTARG}"
            if [[ ! -r "${OPTARG}" ]] ; then
                echo
                echo "The inputfile ${OPTARG} can't be read."
            fi
            if [[ -n "${OUTPUTFILE}" ]] ; then
                echo
                echo "You cannot define both -I input and -O output."
                USAGE
                exit 1
            fi;;
        O ) OUTPUTFILE="${OPTARG}"
            DEFAULTBASEFILE="${OPTARG}"
            if [[ -n "${INPUTFILE}" ]] ; then
                echo
                echo "You cannot define both -I input and -O output."
                USAGE
                exit 1
            fi;;
        t ) TAG="${OPTARG}";;
#ignore the individual file options, because you don't know what they should be.
        A ) ;;
        b ) ;;
        c ) ;;
        d ) ;;
        D ) ;;
        i ) ;;
        l ) ;;
        p ) ;;
        s ) ;;
        h ) USAGE
            exit 1;;
        \? ) USAGE
            exit 1;;
        * ) USAGE
            exit 1;;
    esac
done

if [[ -z "${INPUTFILE}" && -z "${OUTPUTFILE}" ]] ; then
    echo
    echo "You must define either -I input or -O output."
    USAGE
    exit 1
fi

# now the script is either going to fill an -O OUTPUT file with the contents of
# -b -c -d -D -i -l -p -s OR the script will use the -I INPUT file and
# split into component parts to be put into -b -c -d -D -i -l -p -s

# fill in the default base filenames
# note that IPNRC is initialized to empty here so that we can fill in its
# default filename below only if the user did not specify one.
if [[ -n "${TAG}" ]] ; then
    DEFAULTBASEFILE="${DEFAULTBASEFILE}.${TAG}"
fi
BPRC="${DEFAULTBASEFILE}.bprc"
DTN2RC="${DEFAULTBASEFILE}.dtn2rc"
DTPCRC="${DEFAULTBASEFILE}.dtpcrc"
IONRC="${DEFAULTBASEFILE}.ionrc"
LTPRC="${DEFAULTBASEFILE}.ltprc"
IONSECRC="${DEFAULTBASEFILE}.ionsecrc"
CFDPRC="${DEFAULTBASEFILE}.cfdprc"
# these variables are initialized later
IPNRC=""

# reset options index to reuse getopts
OPTIND=1
options=""
while getopts ":i:d:D:c:p:b:l:I:O:t:s:hA" options; do
    case $options in
        i ) IONRC_FILES+=("${OPTARG}");;
        d ) DTN2RC="${OPTARG}";;
        D ) DTPCRC="${OPTARG}";;
        p ) IPNRC="${OPTARG}";;
        b ) BPRC_FILES+=("${OPTARG}");;
        c ) CFDPRC="${OPTARG}";;
        l ) LTPRC="${OPTARG}";;
        s ) IONSECRC="${OPTARG}";;
        A ) append="TRUE";;
# the input, output, tag options have already been used, ignore them
        I ) ;;
        O ) ;;
        t ) ;;
        h ) USAGE
            exit 1;;
        \? ) USAGE
            exit 1;;
        * ) USAGE
            exit 1;;
    esac
done

# Fill in the default base filenames here if necessary instead of above so we have a
# way to detect if both were specified by the user, which is not allowed.
if [[ -z "${IPNRC}" ]]  ; then
    IPNRC="${DEFAULTBASEFILE}.ipnrc"
fi

# if there is an input file, we will convert INPUTFILE -> ionrc, dtn2rc, ipnrc, etc
if [[ -n "${INPUTFILE}" ]] ; then
    echo
    echo "I will now split the large input configuration file into its component parts."
    echo
    awk -f "${AWKSCRIPT}" -v configfile="${INPUTFILE}" -v tag="${TAG}" -v echo="cat" -v append="${append}" -v ionrc="${IONRC}" -v ltprc="${LTPRC}" -v bprc="${BPRC}" -v cfdprc="${CFDPRC}" -v ipnrc="${IPNRC}" -v dtn2rc="${DTN2RC}" -v dtpcrc="${DTPCRC}" -v ionsecrc="${IONSECRC}" "${INPUTFILE}"
else
# there is an OUTPUTFILE, which will contain the contents of ionrc, dtn2rc, ipnrc etc.
    datenow=$(date)
    if [[ "${append}" == "TRUE" ]] ; then
        echo
        echo "I will now append the individual configuration files into one large file."
        echo "## File modified by ${0}" >>"${OUTPUTFILE}"
        echo "## ${datenow}" >>"${OUTPUTFILE}"
        echo "## Run the following command to start ION node:" >>"${OUTPUTFILE}"
        echo "##    % ionstart -I \"${OUTPUTFILE}\"" >>"${OUTPUTFILE}"

    else
        echo
        echo "I will now create a new configuration file."
        echo "## File created by ${0}" >"${OUTPUTFILE}"
        echo "## ${datenow}" >>"${OUTPUTFILE}"
        echo "## Run the following command to start ION node:" >>"${OUTPUTFILE}"
        echo "##    % ionstart -I \"${OUTPUTFILE}\"" >>"${OUTPUTFILE}"
    fi
    # Process each IONRC file in the order provided
    if [[ -r "${IONRC_FILES[0]}" ]]; then
        # add header
        echo
        echo "Appending ${IONRC_FILES[*]} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin ionadmin ${TAG}" >>"${OUTPUTFILE}"
        #
        for IONRC in "${IONRC_FILES[@]}"; do
            if [[ -r "${IONRC}" ]] ; then
                echo >>"${OUTPUTFILE}"
                cat "${IONRC}" >>"${OUTPUTFILE}"
            fi
        done
        # add trailer
        echo "## end ionadmin ${TAG}" >>"${OUTPUTFILE}"
    fi

    if [[ -r "${IONSECRC}" ]] ; then
        echo
        echo "Appending ${IONSECRC} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin ionsecadmin ${TAG}" >>"${OUTPUTFILE}"
        cat "${IONSECRC}" >>"${OUTPUTFILE}"
        echo >>"${OUTPUTFILE}"
        echo "## end ionsecadmin ${TAG}" >>"${OUTPUTFILE}"
    fi
    if [[ -r "${LTPRC}" ]] ; then
        echo
        echo "Appending ${LTPRC} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin ltpadmin ${TAG}" >>"${OUTPUTFILE}"
        cat "${LTPRC}" >>"${OUTPUTFILE}"
        echo >>"${OUTPUTFILE}"
        echo "## end ltpadmin ${TAG}" >>"${OUTPUTFILE}"
    fi

    # Process each BPRC file in the order provided
    if [[ -r "${BPRC_FILES[0]}" ]]; then
        # add header
        echo
        echo "Appending ${BPRC_FILES[*]} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin bpadmin ${TAG}" >>"${OUTPUTFILE}"
        #
        for BPRC in "${BPRC_FILES[@]}"; do
            if [[ -r "${BPRC}" ]] ; then
                echo >>"${OUTPUTFILE}"
                cat "${BPRC}" >>"${OUTPUTFILE}"
            fi
        done
        # add trailer
        echo >>"${OUTPUTFILE}"
        echo "## end bpadmin ${TAG}" >>"${OUTPUTFILE}"
    fi


    if [[ -r "${CFDPRC}" ]] ; then
        echo
        echo "Appending ${CFDPRC} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin cfdpadmin ${TAG}" >>"${OUTPUTFILE}"
        cat "${CFDPRC}" >>"${OUTPUTFILE}"
        echo >>"${OUTPUTFILE}"
        echo "## end cfdpadmin ${TAG}" >>"${OUTPUTFILE}"
    fi
    if [[ -r "${IPNRC}" ]] ; then
        echo
        echo "Appending ${IPNRC} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin ipnadmin ${TAG}" >>"${OUTPUTFILE}"
        cat "${IPNRC}" >>"${OUTPUTFILE}"
        echo >>"${OUTPUTFILE}"
        echo "## end ipnadmin ${TAG}" >>"${OUTPUTFILE}"
    fi
    if [[ -r "${DTN2RC}" ]] ; then
        echo
        echo "Appending ${DTN2RC} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin dtn2admin ${TAG}" >>"${OUTPUTFILE}"
        cat "${DTN2RC}" >>"${OUTPUTFILE}"
        echo >>"${OUTPUTFILE}"
        echo "## end dtn2admin ${TAG}" >>"${OUTPUTFILE}"
    fi
    if [[ -r "${DTPCRC}" ]] ; then
        echo
        echo "Appending ${DTPCRC} into ${OUTPUTFILE}."
        echo >>"${OUTPUTFILE}"
        echo "## begin dtpcadmin ${TAG}" >>"${OUTPUTFILE}"
        cat "${DTPCRC}" >>"${OUTPUTFILE}"
        echo >>"${OUTPUTFILE}"
        echo "## end dtpcadmin ${TAG}" >>"${OUTPUTFILE}"
    fi
fi

echo
echo "ION configuration creation script completed."
