#!/bin/bash
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE
#------------------------------------------------------------------------------

# This script is designed to rebuild an Edge server from a seed checkpoint from
# the master WHILE KEEPING THE EXISTING EDGE SPECIFIC DATA.
#
# You have to first copy the seed checkpoint from the master, created with
# edge_dump.sh, to the edge server before running this script.  (Alternately,
# a full checkpoint from the master can be used so long as the edge server
# spec does not specify any filtering, e.g. does not use ArchiveDataFilter.)

# Then run this script on the Edge server with the instance number and full
# path of the master seed checkpoint as parameters.
#
# Run example:
#  ./recover_edge.sh 1 /p4/1/checkpoints/p4_1.edge_syd.seed.ckp.9188.gz

set -u

declare ExcludedTables=
declare CheckpointTables=
declare Cmd=
declare EdgeCheckpointsDir=
declare EdgeDump=
declare NewEdgeCheckpoint=


function usage () {
   echo -e "Usage:\n\t${0##*/} <SDP_Instance> <EdgeSeedCheckpoint>\n"
   exit 1
}

[[ $# -ne 2 || ${1:-Unset} == -h ]] && usage

export SDP_INSTANCE=${SDP_INSTANCE:-Undefined}
export SDP_INSTANCE=${1:-$SDP_INSTANCE}
if [[ $SDP_INSTANCE == Undefined ]]; then
   echo -e "Usage Error: Instance parameter not supplied."
   usage
fi

declare EdgeSeedCheckpoint=${2:-Unset}
if [[ "$EdgeSeedCheckpoint" == Unset ]]; then
   echo -e "Usage Error: EdgeSeedCheckpoint parameter not supplied.  Usage:\n\t${0##*/} <SDP_Instance> <EdgeSeedCheckpoint>\n"
   echo "You must supply the Perforce instance as the second parameter to this script."
   exit 1
fi

# shellcheck disable=SC1091
source /p4/common/bin/p4_vars "$SDP_INSTANCE"
# shellcheck disable=SC1091
source /p4/common/bin/backup_functions.sh
# shellcheck disable=SC1091
source /p4/common/bin/edge_vars
export LOGFILE=
LOGFILE="$LOGS/recover_edge.$(date +'%Y%m%d-%H%M').log"

[[ -n "$ExcludedTables" && -n "$CheckpointTables" ]] ||\
   die "Values for \$ExcludedTables and/or \$CheckpointTables not defined in $P4CBIN/edge_vars."

######### Start of Script ##########

EdgeCheckpointsDir="${CHECKPOINTS}.${SERVERID#p4d_}"
EdgeDump="$EdgeCheckpointsDir/${P4SERVER}.$(date +'%Y%m%d-%H%M').edge_dump"

echo "Processing. This may take a while depending on checkpoint duration."
echo "Log file is: $LOGFILE"

check_vars
set_vars
ckp_running

log "Remove offline db"
rm -f "$OFFLINE_DB"/db.* > "$LOGFILE" 2>&1

# With -K filter out the various Edge-specific tables to be replaced with 
# current live versions.

log "Recover checkpoint from master into offline_db skipping tables not used on the edge."
Cmd="$P4DBIN -r $OFFLINE_DB -K $ExcludedTables -z -jr $EdgeSeedCheckpoint"

log "Running: $Cmd"
$Cmd >> "$LOGFILE" 2>&1 || die "Failed to recover from $EdgeSeedCheckpoint."

log "Stopping the edge server."
stop_p4d

# With -k we filter and only checkpoint the specified tables from the current live Edge DB.

Cmd="$P4DBIN -r $P4ROOT -k $CheckpointTables -jd $EdgeDump"
log "Creating a dump of the edge specific data from P4ROOT."

log "Running: $Cmd"
$Cmd >> "$LOGFILE" 2>&1 ||\
   die "Failed to dump to $EdgeDump"

log "Recover the edge dump into offline_db"
Cmd="$P4DBIN -r $OFFLINE_DB -jr $EdgeDump"
log "Running: $Cmd"

$Cmd >> "$LOGFILE" 2>&1 ||\
   die "Failed to recover from $EdgeDump"

log "Reset the replication state and clear the P4ROOT folder db files."
# shellcheck disable=SC2129
rm -f "$P4ROOT"/db.* >> "$LOGFILE" 2>&1
rm -f "$P4ROOT"/state >> "$LOGFILE" 2>&1
rm -f "$P4ROOT"/rdb.lbr >> "$LOGFILE" 2>&1
rm -f "$P4JOURNAL" >> "$LOGFILE" 2>&1

log "Move the rebuilt database to P4ROOT"
mv "$OFFLINE_DB"/db.* "$P4ROOT"/. >> "$LOGFILE" 2>&1

log "Start the edge server back up."
start_p4d

log "Recreate the offline_db"
Cmd="$P4DBIN -r $OFFLINE_DB -K $ExcludedTables -jr -z $EdgeSeedCheckpoint"
log "Running: $Cmd"
$Cmd >> "$LOGFILE" 2>&1

Cmd="$P4DBIN -r $OFFLINE_DB -jr $EdgeDump"
log "Running: $Cmd"
$Cmd >> "$LOGFILE" 2>&1

log "Create a new edge checkpoint from offline_db"
get_offline_journal_num

NewEdgeCheckpoint="$EdgeCheckpointsDir/${P4SERVER}.${SERVERID#p4d_}.ckp.$((OFFLINEJNLNUM+1)).gz"

Cmd="$P4DBIN -r $OFFLINE_DB -jd -z $NewEdgeCheckpoint"
log "Running: $Cmd"
$Cmd >> "$LOGFILE" 2>&1

ckp_complete
log "End $P4SERVER Recover Edge"
mail_log_file "$HOSTNAME $P4SERVER Recover Edge log."
