#!/usr/bin/env bash

set -eu -o pipefail

readonly INSTALL_DESTINATION="/usr/sap/$SAPSYSTEMNAME/SYS/global/hdb/opt/backint/backint-gcs"
readonly GCS_BUCKET="https://www.googleapis.com/download/storage/v1/b/cloudsapdeploy/o/backint-gcs"
readonly LATEST="$GCS_BUCKET%2FLATEST.txt"
readonly PACKAGE_BASE="$GCS_BUCKET%2Fsap-backint-gcs"
readonly USER_AGENT="sap-backint-gcs-installer/1.0 (GPN: SAP Backint for GCS)"
readonly LOGS_DIR="$INSTALL_DESTINATION/logs"
readonly LOGGING_PROPERTIES="$INSTALL_DESTINATION/logging.properties"
readonly PARAMETERS_FILE="$INSTALL_DESTINATION/parameters.txt"
readonly UPDATE_LOCK="$INSTALL_DESTINATION/.updating.lock"

download () {
    # Downloads and unzips the archive from GCS
    # $1 - latest version number
    local version="$1"
    local package="${PACKAGE_BASE}-${version}.tar.gz"
    local archive="sap-backint-gcs.tar.gz"
    curl --show-error --silent --fail --user-agent "$USER_AGENT" \
        --output "$INSTALL_DESTINATION/$archive" "${package}?alt=media"
    # save existing net.properties
    if [[ -f "$INSTALL_DESTINATION/jre/conf/net.properties" ]]; then
      cp -f "$INSTALL_DESTINATION/jre/conf/net.properties" "$INSTALL_DESTINATION/jre/conf/net.properties.installsave"
    fi
    tar -xz --directory "$INSTALL_DESTINATION" -f "$INSTALL_DESTINATION/$archive"
    # restore saved net.properties if needed
    if [[ -f "$INSTALL_DESTINATION/jre/conf/net.properties.installsave" ]]; then
      mv "$INSTALL_DESTINATION/jre/conf/net.properties.installsave" "$INSTALL_DESTINATION/jre/conf/net.properties"
    fi
    echo "$version" | tee "$INSTALL_DESTINATION/VERSION.txt" > /dev/null
    # get the update script
    curl --show-error --silent --fail --user-agent "$USER_AGENT" \
        --output "$INSTALL_DESTINATION/update.sh" \
        "https://storage.googleapis.com/cloudsapdeploy/backint-gcs/update.sh"
    # get the send_metrics script
    curl --show-error --silent --fail --user-agent "$USER_AGENT" \
        --output "$INSTALL_DESTINATION/send_metrics.sh" \
        "https://storage.googleapis.com/cloudsapdeploy/backint-gcs/send_metrics.sh" || true
    rm "$INSTALL_DESTINATION/$archive"
}

create_logging_properties() {
    # Creates the logging properties file
    cat > "$LOGGING_PROPERTIES" <<EOF
.level = INFO
com.google.cloud.partners.handlers = java.util.logging.FileHandler
java.util.logging.SimpleFormatter.format=%1\$tY-%1\$tm-%1\$tdT%1\$tH:%1\$tM:%1\$tS.%1\$tL%1\$tZ %4\$s - %5\$s%6\$s%n
java.util.logging.FileHandler.pattern = ${LOGS_DIR}/backint-gcs-%u.log
java.util.logging.FileHandler.append = true
java.util.logging.FileHandler.count = 100
java.util.logging.FileHandler.limit = 10485760
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
EOF
    chmod 0644 "$LOGGING_PROPERTIES"
}

create_parameters_file() {
    # Creates the custom backint parameters file
    cat > "$PARAMETERS_FILE" <<EOF
#BUCKET <GCS Bucket Name>
#DISABLE_COMPRESSION
EOF
      chmod 0644 "$PARAMETERS_FILE"
      echo "Please update \"$PARAMETERS_FILE\" with your GCS bucket name." \
          "If you are not using Application Default Credentials, you must save your GCP Service" \
          "Account credentials to file and add a line containing #SERVICE_ACCOUNT"\
          "<path_to_creds> to \"$PARAMETERS_FILE\""
}

create_backint() {
    # Creates the backint executable script based on the current version
    # $1 - latest version number
    local jar="$(ls $INSTALL_DESTINATION/*$version.jar)"
    cat > "$INSTALL_DESTINATION/backint" <<EOF
#!/usr/bin/env bash

readonly SCRIPT="\$0"
readonly ARGUMENTS="\$@"

wait_for_update() {
    # If an update is in progress, wait for up to 10 seconds
    local checks=10
    while (( checks > 0 ))
    do
        [[ ! -a "$UPDATE_LOCK" ]] && return 0
        echo "\$(date +'%Y-%m-%d %H:%M:%S %Z') - Update in progress, wait for \${checks}s" >> \\
            "${LOGS_DIR}/installation.log"
        sleep 1
        (( checks -= 1 ))
    done
    echo "\$(date +'%Y-%m-%d %H:%M:%S %Z') - Update did not complete after 10s continuing with backup" >> \\
        "${LOGS_DIR}/installation.log"
    return 1
}

main() {
    # Main execution sequence
    if [[ -a "$UPDATE_LOCK" ]]
    then
        wait_for_update
    fi

    # Invoke the backint JAR
    ${INSTALL_DESTINATION}/jre/bin/java \\
        -Djava.util.logging.config.file=${INSTALL_DESTINATION}/logging.properties \\
        -jar ${jar} \$ARGUMENTS >java_std.log 2>java_err.log

}

main
EOF
    chmod 0755 "$INSTALL_DESTINATION/backint"
}

install() {
    # Creates the backint logging properties file, parameters file, executable script and symlinks
    # $1 - latest version number
    local version="$1"

    # Create logging properties file (if non-existent)
    if [[ ! -a "$LOGGING_PROPERTIES" ]]
    then
        create_logging_properties
    fi

    # Create parameter file (if non-existent)
    if [[ ! -a "$PARAMETERS_FILE" ]]
    then
        create_parameters_file
    fi

    # Create the backint executable
    create_backint "$version"

    # Make symlinks
    ln -sf "$INSTALL_DESTINATION/backint" "/usr/sap/$SAPSYSTEMNAME/SYS/global/hdb/opt/hdbbackint"
    if [[ ! -d "/usr/sap/$SAPSYSTEMNAME/SYS/global/hdb/opt/hdbconfig/" ]]
    then
        mkdir "/usr/sap/$SAPSYSTEMNAME/SYS/global/hdb/opt/hdbconfig/"
    fi
    ln -sf "$PARAMETERS_FILE" "/usr/sap/$SAPSYSTEMNAME/SYS/global/hdb/opt/hdbconfig/"

    [[ -d "$LOGS_DIR" ]] || mkdir -p -m 0755 "$LOGS_DIR"
    chmod 0755 $INSTALL_DESTINATION/send_metrics.sh
    $INSTALL_DESTINATION/send_metrics.sh "-n" "backint" "-v" "$version" "-s" "INSTALLED" || true
    echo "$(date +'%Y-%m-%d %H:%M:%S %Z') - Installed version $version" \
        >> "$LOGS_DIR/installation.log"

    echo ""
    echo "*********************************************************************"
    echo ""
    echo "This functionality has been replaced by the Agent for SAP"
    echo "Please upgrade to the Agent for SAP"
    echo "https://cloud.google.com/solutions/sap/docs/agent-for-sap/latest/all-guides"
    echo ""
    echo "*********************************************************************"
    echo ""
}

main() {
    local latest="$(curl --show-error --silent --fail --user-agent "$USER_AGENT" \
        --output - "${LATEST}?alt=media")"
    [[ -d "$INSTALL_DESTINATION" ]] || mkdir -p -m 0755 "$LOGS_DIR"
    download $latest
    install $latest
}

main

