#!/bin/bash

set -e

function bold {
    echo -e "\e[1m${1}\e[0m"
}

function error {
    bold "ERROR: $1"
    exit 1
}

function error_envvar_not_set {
    # $1 missing variable
    # $2 optional reason
    error "environment variable not set: ${1}\n
           ${2}\n
           Please run the container passing the '-e ${1}=value' argument."
}

DAEMON="${DAEMON}"
VERSION="${VERSION}"
RS_ASN="${RS_ASN}"
PLACEHOLDER_16BIT_ASN="${PLACEHOLDER_16BIT_ASN}"
ROUTER_ID="${ROUTER_ID}"
LOCAL_PREFIXES="${LOCAL_PREFIXES}"
IP_VER="${IP_VER}"
LOCAL_FILES="${LOCAL_FILES}"
LOCAL_FILES_DIR="${LOCAL_FILES_DIR}"
TEMPLATES_DIR="${TEMPLATES_DIR}"
EURO_IX_URL="${EURO_IX_URL}"
EURO_IX_IXP_ID="${EURO_IX_IXP_ID}"

CLIENTS_FILE_PATH="/root/clients.yml"
OUTPUT_DIR="/root/arouteserver_configs"
OUTPUT_DIR_HTML="/root/arouteserver_html"

if [[ ! -e "${OUTPUT_DIR}" && ! -d "${OUTPUT_DIR}" ]]; then
    error "The output directory ${OUTPUT_DIR} can't be found.
          This is the directory where the configurations generated by ARouteServer will be saved.
          Please be sure to mount the desired directory of the host to the ${OUTPUT_DIR} directory on the container.
          You can run the container passing the '-v PATH_OF_DIRECTORY_ON_THE_HOST:${OUTPUT_DIR}' argument."
fi

if [[ -n "${TEMPLATES_DIR}" ]]; then
    if [[ ! -e "${TEMPLATES_DIR}" ]]; then
        error "Couldn't find the directory ${TEMPLATES_DIR} on the container.\n
               Please mount the local directory where the templates are stored using '-v PATH_OF_TEMPLATES_DIR_ON_THE_HOST:${TEMPLATES_DIR}:ro' argument."
    fi
fi

TEST_WRITABLE_FILE="${OUTPUT_DIR}/.test_dir_is_writable"

set +e
touch ${TEST_WRITABLE_FILE} &>/dev/null
EXIT_CODE=$?
set -e

if [[ ${EXIT_CODE} -ne 0 ]]; then
    error "It seems that the output directory ${OUTPUT_DIR} is not writable.
          This is the directory where the configurations generated by ARouteServer will be saved.
          Please be sure to mount the desired directory of the host to the ${OUTPUT_DIR} directory on the container.
          You can run the container passing the '-v PATH_OF_DIRECTORY_ON_THE_HOST:${OUTPUT_DIR}' argument."
fi

rm ${TEST_WRITABLE_FILE} &>/dev/null

if [[ -e "${OUTPUT_DIR_HTML}" && -d "${OUTPUT_DIR_HTML}" ]]; then

    TEST_WRITABLE_FILE="${OUTPUT_DIR_HTML}/.test_dir_is_writable"

    set +e
    touch ${TEST_WRITABLE_FILE} &>/dev/null
    EXIT_CODE=$?
    set -e

    if [[ ${EXIT_CODE} -ne 0 ]]; then
        error "It seems that the HTML output directory ${OUTPUT_DIR_HTML} is not writable.
              This is the directory where the textual representation of route server policy generated by ARouteServer will be saved.
              Please be sure to mount the desired directory of the host to the ${OUTPUT_DIR_HTML} directory on the container.
              You can run the container passing the '-v PATH_OF_DIRECTORY_ON_THE_HOST:${OUTPUT_DIR_HTML}' argument."
    fi

    rm ${TEST_WRITABLE_FILE} &>/dev/null
fi

if [[ -z "${DAEMON}" ]]; then
    error_envvar_not_set "DAEMON"
fi

if [[ -z "${VERSION}" ]]; then
    error_envvar_not_set "VERSION"
fi

if [[ -n "${EURO_IX_URL}" ]]; then

    echo ""
    echo "Generating clients.yaml from EURO IX-F"
    echo ""
    arouteserver clients-from-euroix -o "${CLIENTS_FILE_PATH}" --url "${EURO_IX_URL}" "${EURO_IX_IXP_ID}"
fi

if [[ ! -e "${CLIENTS_FILE_PATH}" ]]; then
    error "Couldn't find the file ${CLIENTS_FILE_PATH} on the container.\n
           Please mount the local file where the list of clients is defined using '-v PATH_OF_CLIENTS_FILE_ON_THE_HOST:${CLIENTS_FILE_PATH}:ro' argument."
fi

IP_VER_ARG=""
OUTPUT_FILE="${DAEMON}.cfg"

if [[ "${DAEMON}" == "bird" ]]; then
    set +e
    egrep "^1\." <<< "${VERSION}" &>/dev/null
    IP_VER_REQUIRED=$?  # 0 = IP_VER is required
    set -e

    if [[ ${IP_VER_REQUIRED} -eq 0 ]]; then
        if [[ -z "${IP_VER}" ]]; then
            error_envvar_not_set "IP_VER" "When BIRD 1.x is used, IP_VER must be set."
        fi
    fi
fi

if [[ -n "${IP_VER}" ]]; then
    # Accept only 4 or 6
    if [[ "${IP_VER}" != "4" && "${IP_VER}" != "6" ]]; then
        error "Invalid value for IP_VER: ${IP_VER}\n
               The value must be either 4 or 6."
    fi

    IP_VER_ARG="--ip-ver ${IP_VER}"
    OUTPUT_FILE="${DAEMON}${IP_VER}.cfg"
fi

if [[ ! -e /etc/arouteserver/general.yml ]]; then
    if [[ -z "${RS_ASN}" ]]; then
        error_envvar_not_set "RS_ASN"
    fi

    if [[ ${RS_ASN} -gt 65535 ]]; then
        if [[ -z "${PLACEHOLDER_16BIT_ASN}" ]]; then
            error_envvar_not_set "PLACEHOLDER_16BIT_ASN"
        else
            comms_asn_optional_arg="comms_asn=${PLACEHOLDER_16BIT_ASN}"
        fi
    else
        comms_asn_optional_arg=""
    fi

    if [[ -z "${ROUTER_ID}" ]]; then
        error_envvar_not_set "ROUTER_ID"
    fi

    if [[ -z "${LOCAL_PREFIXES}" ]]; then
        error_envvar_not_set "LOCAL_PREFIXES"
    fi

    echo ""
    bold "Configuring ARouteServer for ${DAEMON} ${VERSION}..."
    echo ""

    arouteserver \
        configure --preset-answer \
            daemon=${DAEMON} \
            version=${VERSION} \
            asn=${RS_ASN} \
            ${comms_asn_optional_arg} \
            router_id=${ROUTER_ID} \
            black_list=${LOCAL_PREFIXES}
else
    echo ""
    bold "The user-provided configuration from general.yml will be used."
    echo ""
fi

if [[ -e "${OUTPUT_DIR_HTML}" && -d "${OUTPUT_DIR_HTML}" ]]; then
    OUTPUT_FILE_HTML="${DAEMON}.html"

    echo ""
    echo "Generating HTML textual representation of route server's options and policies"
    echo ""

    OUTPUT_PATH_HTML="${OUTPUT_DIR_HTML}/${OUTPUT_FILE_HTML}"

    arouteserver \
        html \
        --clients "${CLIENTS_FILE_PATH}" \
        -o "${OUTPUT_PATH_HTML}"

    echo ""
    bold "Textual representation of route server policy for ${DAEMON} saved to ${OUTPUT_PATH_HTML} (path on the container)."
    echo "You will find the textual representation file in your host system, inside the directory that you mounted at run-time."
    echo ""
fi

echo ""
bold "Generating route server configuration for ${DAEMON} ${VERSION}..."
echo ""

LOCAL_FILES_ARG=""
LOCAL_FILES_DIR_ARG=""

if [[ -n "${LOCAL_FILES}" ]]; then
    LOCAL_FILES_ARG="--use-local-files ${LOCAL_FILES}"

    if [[ -n "${LOCAL_FILES_DIR}" ]]; then
        LOCAL_FILES_DIR_ARG="--local-files-dir ${LOCAL_FILES_DIR}"
    fi
fi

TEMPLATES_DIR_ARG=""

if [[ -n "${TEMPLATES_DIR}" ]]; then
    TEMPLATES_DIR_ARG="--templates-dir ${TEMPLATES_DIR}"
fi

OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_FILE}"

arouteserver \
    "${DAEMON}" \
    ${TEMPLATES_DIR_ARG} \
    --target-version "${VERSION}" \
    ${IP_VER_ARG} \
    --clients "${CLIENTS_FILE_PATH}" \
    ${LOCAL_FILES_ARG} \
    ${LOCAL_FILES_DIR_ARG} \
    -o "${OUTPUT_PATH}"

echo ""
bold "Route server configuration for ${DAEMON} ${VERSION} saved to ${OUTPUT_PATH} (path on the container)."
echo "You will find the configuration file in your host system, inside the directory that you mounted at run-time."
echo ""
