#!/bin/sh
#
# 01. "should check code directly not $?"
# shellcheck disable=2181
#
# 02. "can't follow . import"
# shellcheck disable=1090,1091
#
# 03. "possible misspelling"
# shellcheck disable=2153
#
# 04. "use find .. over ls"
# shellcheck disable=2011
# -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

# ===================================================
# 01. Attempt to load global DayZ values
# ===================================================
echo "Starting, attempting to load globals.sh"

GLOBALS_FILE="$PWD/lib/globals.sh"
if [ -e "$GLOBALS_FILE" ] ; then
    chmod +x "$GLOBALS_FILE"
    . "$GLOBALS_FILE"
else
    die "Could not load: $GLOBALS_FILE"
fi

# ===================================================
# 02. Local script variables
# ===================================================
export STEAMCMD_USER=steam
export MODLISTS="$PWD/modlists"

export LOCAL_STOCK="$HOME/stock"
export LOCAL_STOCK_GAME="$LOCAL_STOCK/DayZ"
export LOCAL_STOCK_SERVER="$LOCAL_STOCK/DayZServer"
export LOCAL_MODS="$HOME/mods"

# ===================================================
# 03. Mount network drive
# ===================================================
if ! is_network_drive_mounted ; then
    mount_dayz_network_drive

    if ! is_network_drive_mounted ; then
        die "Could not mount network drive"
    fi
fi

# ===================================================
# 04. Checks
# ===================================================
check() {
    mkdir -p "$LOCAL_STOCK_GAME" "$LOCAL_STOCK_SERVER" "$LOCAL_MODS"

    if [ "$USER" != "$STEAMCMD_USER" ] ; then
        die "Current user: '$USER' does not match '$STEAMCMD_USER'"
    fi

    if [ ! -d "$MODLISTS" ] ; then
        die "Could not find modlists at: $MODLISTS"
    fi

    if [ ! -d "$REMOTE_MODS" ] ; then
        die "Could not find remote mods at: $REMOTE_MODS"
    fi

    if [ ! -d "$REMOTE_MAPS" ] ; then
        die "Could not find remote maps at: $REMOTE_MAPS"
    fi

    if islocked_remote_server ; then
        die "Remote server already locked?"
    fi

    msg "Health checks passed successfully."
}

# ===================================================
# 05. Begin functions
# ===================================================
update_server() {
    msg "============== UPDATING DAYZ SERVER ================="
    steamcmd -tcp \
        +force_install_dir "$LOCAL_STOCK_SERVER" \
        +@sSteamCmdForcePlatformType windows \
        +@ShutdownOnFailedCommand 1 \
        +login "$STEAM_USER" \
        +app_update "$DAYZ_SERVER_ID" \
        +quit

    is_network_drive_mounted &&
    do_sync "$LOCAL_STOCK_SERVER"/ "$REMOTE_STOCK_SERVER"
    msg "============ DONE UPDATING SERVER ====================="
}

update_game() {
    msg "========== UPDATING DAYZ GAME ================"
    steamcmd -tcp \
        +force_install_dir "$LOCAL_STOCK_GAME" \
        +@sSteamCmdForcePlatformType windows \
        +@ShutdownOnFailedCommand 1 \
        +login "$STEAM_USER" \
        +app_update "$DAYZ_GAME_ID" \
        +quit

    is_network_drive_mounted &&
    do_sync "$LOCAL_STOCK_GAME"/ "$REMOTE_STOCK_GAME"
    msg "============= DONE UPDATING GAME ==================="
}

# args: $1 = server_modlist.txt to update
update_mods_for_server() {
    msg "======= UPDATING MODS FOR MAP: $1 ========"

    mods_file="$MODLISTS/$1"
    map_name=${1%.txt}
    remote_map_mod_dir="$REMOTE_MODS/$map_name"
    mkdir -p "$remote_map_mod_dir"

    # Create temporary file to list all the mod_id's we are
    # going to download. This speeds up steamcmd and avoids rate limits.
    tempfile="/tmp/$map_name-mods_to_download.txt"
    :> "$tempfile"

    # load the server_modlist.txt, copying the mod id's we need to update
    # to the temp file, while skipping comments and blank lines
    #
    # format should be: "mod_id^nickname"
    #
    #      # Dabs Framework
    #      # https://steamcommunity.com/sharedfiles/filedetails/?id=2545327648
    #      2545327648^dabsframework
    #
    while read -r mod ; do
        case "$mod" in
            \#*|''|' ')
                ;;
            *)
                mod=${mod%%^*}

        # check validity of syntax
        if [ -z "$mod" ] ; then
            die "mod for $map_name appears to be empty - syntax error"
        fi

        printf "+workshop_download_item $DAYZ_GAME_ID %s\n" "$mod" >> "$tempfile"
    esac
    done <"$mods_file"
    unset mod

    # shellcheck disable=2046
    steamcmd \
    -tcp \
        +force_install_dir "$LOCAL_MODS" \
        +@sSteamCmdForcePlatformType windows \
        +@ShutdownOnFailedCommand 1 \
    +login "$STEAM_USER" \
    $(xargs < "$tempfile") \
    +quit

    if [ $? -ne 0 ] ; then
    die "Problem downloading mods for $map_name"
    fi

    msg "------------ RENAMING MODS -------------"
    mods_to_copy="$LOCAL_MODS/mods_to_copy"
    rm -rf "$mods_to_copy" 2>/dev/null ||:
    mkdir -p "$mods_to_copy"

    :> "$mods_to_copy/mods.txt"
    while read -r mod ; do
        # skip comments, blank lines
        case "$mod" in
            \#*|''|' ')
                ;;
            *)
            mod_id=${mod%%^*}
            mod_name=${mod##*^}
            if [ ! -d "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$mod_id" ] ; then
                die "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$mod_id does not exist"
            fi
            cp -raf "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$mod_id" "$mods_to_copy/@${mod_name}"
            printf '@%s\n' "$mod_name" >> "$mods_to_copy/mods.txt"
        esac
    done < "$mods_file"

    msg "----------- SYNCING MODS -------------"
    do_sync "$mods_to_copy"/ "$remote_map_mod_dir"

    rm -f "$tempfile" 2>/dev/null ||:
    unset tempfile mod map_name mods_file mods_to_copy mod_name mod_id remote_map_mod_dir

    msg "======= DONE UPDATING MODS FOR: $1 ========"
}

update_stock_maps() {
    msg "----------- UPDATING MAPS -------------"

    msg "Copying Stock Chernarus"
    do_sync \
        "$LOCAL_STOCK_SERVER/mpmissions/$CHERNARUS_MAP_NAME"/ \
        "$REMOTE_MAPS/$CHERNARUS_MAP_NAME"

    msg "Updating Namalsk Survival"
    steamcmd \
        -tcp \
        +force_install_dir "$LOCAL_MODS" \
        +@sSteamCmdForcePlatformType windows \
        +@ShutdownOnFailedCommand 1 \
        +login "$STEAM_USER" \
        +workshop_download_item \
        "$DAYZ_GAME_ID" \
        "$NAMALSK_SURVIVAL_MOD_ID" \
        +quit

    if [ $? -ne 0 ] ; then
        die "Failed to update Namalsk Survival"
    fi

    if [ -d "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$NAMALSK_SURVIVAL_MOD_ID/Extras/Regular/$NAMALSK_MAP_NAME" ] ; then
        do_sync "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$NAMALSK_SURVIVAL_MOD_ID/Extras/Regular/$NAMALSK_MAP_NAME"/ \
            "$REMOTE_MAPS/$NAMALSK_MAP_NAME" || \
            die "failed to copy Namalsk map files"
    fi

    msg "Updating Namalsk Island"
    steamcmd \
        -tcp \
        +force_install_dir "$LOCAL_MODS" \
        +@sSteamCmdForcePlatformType windows \
        +@ShutdownOnFailedCommand 1 \
        +login "$STEAM_USER" \
        +workshop_download_item \
        "$DAYZ_GAME_ID" \
        "$NAMALSK_ISLAND_MOD_ID" \
        +quit

    if [ $? -ne 0 ] ; then
        die "Failed to update Namalsk Island"
    fi

    ####################TODO: # msg "Updating Optimized Namalsk Server PBOs"

    msg "Updating TakistanPlus"
    steamcmd \
        -tcp \
        +force_install_dir "$LOCAL_MODS" \
        +@sSteamCmdForcePlatformType windows \
        +@ShutdownOnFailedCommand 1 \
        +login "$STEAM_USER" \
        +workshop_download_item \
        "$DAYZ_GAME_ID" \
        "$TAKISTAN_MOD_ID" \
        +quit

    if [ $? -ne 0 ] ; then
        die "Failed to update TakistanPlus"
    fi

    if [ -d "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$TAKISTAN_MOD_ID/Mission/$TAKISTAN_MAP_NAME" ] ; then
        do_sync "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$TAKISTAN_MOD_ID/Mission/$TAKISTAN_MAP_NAME"/ \
            "$REMOTE_MAPS/$TAKISTAN_MAP_NAME" || \
            die "failed to copy Takistan map files"
    fi
}

main() {
    check || die "Failed to pass health checks"

    lock_remote_server

    update_server
    update_game
    update_stock_maps

    for server in $(ls "$MODLISTS" | xargs) ; do
        if [ ! -f "$MODLISTS/$server" ] ; then
            msg "Could not find modlist for: $MODLISTS/$server"
            continue
        fi
        update_mods_for_server "$server"
        unset server
    done

    unlock_remote_server
}

main "$@" || exit 1
