#!/bin/bash

# --debug  2>&1

export PATH=/usr/local/bin:$PATH

function delete_temp_staging {
  local step="${1:-0}"
  step=$((step + 0))

  if [ "$step" -ge 5 ]; then
    #echo "Reverting step 5: Updating nfd_coming_soon option"
    wp option update nfd_coming_soon 'false'
  fi

  if [ "$step" -ge 4 ]; then
    #echo "Reverting step 4: Removing option staging_config."
    wp option delete staging_config --skip-themes --skip-plugins --quiet
  fi

  if [ "$step" -ge 3 ]; then
    #echo "Reverting step 3: Removing all staging tables"
    wp db query "DROP TABLE IF EXISTS $(wp db tables --all-tables-with-prefix --format=csv | grep '^staging_' | tr '\n' ',' | sed 's/,$//')" --path=$STAGING_DIR --skip-themes --skip-plugins --quiet
  fi

  if [ "$step" -ge 2 ]; then
    #echo "Reverting step 2: Removing option staging_environment"
    cd $PRODUCTION_DIR
    wp option delete staging_environment --skip-themes --skip-plugins --quiet
  fi

  if [ "$step" -ge 1 ]; then
    #echo "Reverting step 1: Removing staging directory..."
    rm -rf "$STAGING_DIR"
  fi

  error "$2"

  #echo "Cleanup completed."
  #exit 1
}

function auth_action {
  cd $CURRENT_DIR || error 'Unable to switch directory.'
  TOKEN=$(wp transient get staging_auth_token --path=$CURRENT_DIR --skip-themes --skip-plugins --quiet)
  if [ "$1" != "$TOKEN" ] || [ -z "$TOKEN" ]; then
    wp transient delete staging_auth_token --path=$CURRENT_DIR
    error 'Unable to authenticate the action.'
  fi
  wp transient delete staging_auth_token --path=$CURRENT_DIR --skip-themes --skip-plugins --quiet
}

function create {
  cd $PRODUCTION_DIR || error 'Unable to move to production directory.'
  WP_VER=$(wp core version)
  mkdir -p $STAGING_DIR || error 'Unable to create staging directory.'
  wp db export $STAGING_DIR/.export-sql --add-drop-table --skip-themes --skip-plugins --quiet --tables=$PRODUCTION_TABLES || {
    delete_temp_staging 1 "Unable to export database."
  }
  wp option update staging_environment production --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 1 "Unable to set environment."
  }
  cd $STAGING_DIR || {
    delete_temp_staging 2 "Unable to move to staging directory."
  }
  move_files $PRODUCTION_DIR $STAGING_DIR
  if [ -L $PRODUCTION_DIR/index.php ]; then
    echo 'path='$STAGING_DIR >/nfssys/etc/wp_symink_watch/$(whoami).notify
    echo 'SetEnv WP_ABSPATH '$STAGING_DIR >.htaccess
  else
    wp core download --version=$WP_VER --force || {
      delete_temp_staging 2 "Unable to install WordPress in staging directory."
    }
  fi
  wp core config --dbhost=$DB_HOST --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbprefix=staging_$DB_PREFIX --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 2 "Unable to configure WordPress."
  }

  tmpfile=$(mktemp)
  while IFS= read -r line; do
    echo "${line//${DB_PREFIX}/staging_${DB_PREFIX}}" >>"$tmpfile"
  done <"$STAGING_DIR/.export-sql"
  mv "$tmpfile" "$STAGING_DIR/.export-sql" || {
    delete_temp_staging 2 "Unable to update database prefix."
  }

  wp db import $STAGING_DIR/.export-sql --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 2 "Unable to import database."
  }
  rm $STAGING_DIR/.export-sql --force
  wp option update staging_environment staging --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 3 "Unable to set environment."
  }
  wp search-replace $PRODUCTION_URL $STAGING_URL --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 3 "Unable to update URLs on staging."
  }
  wp option update staging_config "$CONFIG" --format=json --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 3 "Unable to import global config on staging."
  }
  wp option update nfd_coming_soon 'true' --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 4 "Unable to turn on Coming Soon page in staging."
  }
  wp rewrite flush --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to flush rewrite rules."
  }
  rewrite_htaccess $STAGING_DIR
  clear
  echo \{\"status\" :\"success\",\"message\":\"Staging website created successfully.\",\"reload\":\"true\"\}
}

function clone {
  cd $PRODUCTION_DIR || error 'Unable to move to production directory.'
  STAGING_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$STAGING_DIR --skip-themes --skip-plugins --quiet)
  if [ "0" != "$USER_ID" ]; then
    SESSIONS=$(wp user meta get $USER_ID session_tokens --format=json --path=$STAGING_DIR --skip-themes --skip-plugins --quiet)
  fi
  wp db query "DROP TABLE $STAGING_TABLES;" --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to drop staging database tables."
  }
  wp db export $STAGING_DIR/.export-sql --add-drop-table --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to export database."
  }

  tmpfile=$(mktemp)
  while IFS= read -r line; do
    echo "${line//${DB_PREFIX}/staging_${DB_PREFIX}}" >>"$tmpfile"
  done <"$STAGING_DIR/.export-sql"
  mv "$tmpfile" "$STAGING_DIR/.export-sql" || {
    delete_temp_staging 5 "Unable to update database prefix."
  }
  cd $STAGING_DIR || {
    delete_temp_staging 5 "Unable to move to staging directory."
  }
  wp db import $STAGING_DIR/.export-sql --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to import database."
  }
  if [ "0" != "$USER_ID" ]; then
    wp user meta update $USER_ID session_tokens "$SESSIONS" --format=json --skip-themes --skip-plugins --quiet
  fi
  wp option update staging_environment staging --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to set environment."
  }
  move_files $PRODUCTION_DIR $STAGING_DIR
  if [ -L $PRODUCTION_DIR/index.php ]; then
    echo 'path='$STAGING_DIR >/nfssys/etc/wp_symink_watch/$(whoami).notify
  else
    WP_VER=$(wp core version)
    wp core download --version=$WP_VER --force || {
      delete_temp_staging 5 "Unable to install WordPress in staging directory."
    }
  fi
  wp search-replace $PRODUCTION_URL $STAGING_URL --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to update URLs on staging."
  }
  wp option update staging_config "$CONFIG" --format=json --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to import global config on staging."
  }
  wp option update nfd_coming_soon 'true' --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to turn on Coming Soon page in staging."
  }
  wp rewrite flush --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || {
    delete_temp_staging 5 "Unable to flush rewrite rules."
  }
  rm $STAGING_DIR/.export-sql --force
  rewrite_htaccess $STAGING_DIR
  clear
  echo \{\"status\" :\"success\",\"message\":\"Website cloned successfully.\"\}
}

function deploy_files {
  cd $STAGING_DIR || error 'Unable to move to staging directory.'
  if [ -L $PRODUCTION_DIR/index.php ]; then
    echo 'path='$PRODUCTION_DIR >/nfssys/etc/wp_symink_watch/$(whoami).notify
  else
    WP_VER=$(wp core version)
    wp core download --version=$WP_VER --force --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to move WordPress files.'
  fi
  move_files $STAGING_DIR $PRODUCTION_DIR
  clear
  echo \{\"status\" :\"success\",\"message\":\"Files deployed successfully.\"}
}

function deploy_db {
  cd $STAGING_DIR || error 'Unable to move staging directory.'
  wp db query "DROP TABLE $PRODUCTION_TABLES;" --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || error 'Unable to drop staging tables.'
  wp db export $STAGING_DIR/.export-sql --add-drop-table --skip-themes --skip-plugins --quiet || error 'Unable to export database.'
  sed -i -e "s/staging_$DB_PREFIX/$DB_PREFIX/g" $STAGING_DIR/.export-sql || error 'Unable to update prefix.'
  wp db import $STAGING_DIR/.export-sql --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to import database.'
  wp search-replace "$STAGING_URL" "$PRODUCTION_URL" --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to update URL on production.'
  rm $STAGING_DIR/.export-sql --force
  wp option update staging_environment production --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to set environment.'
  wp option update staging_config "$CONFIG" --format=json --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to import global config on production.'
  wp option delete nfd_coming_soon --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to turn off Coming Soon page.'
  rewrite_htaccess $PRODUCTION_DIR
  clear
  echo \{\"status\" :\"success\",\"message\":\"Database deployed successfully.\"}
}

function deploy_files_db {
  deploy_files
  deploy_db
  clear
  echo \{\"status\" :\"success\",\"message\":\"Files and Database deployed successfully.\"}
}

function deploy_files_dbmerge {
  clear
  # echo \{\"status\" :\"success\",\"message\":\"Files deployed and DB merged successfully.\"\}
}

function destroy {
  cd $PRODUCTION_DIR || error 'Unable to move to production directory.'
  if test -d $STAGING_DIR; then
    STAGING_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$STAGING_DIR --skip-themes --skip-plugins --quiet)
    wp db query "DROP TABLE $STAGING_TABLES;" --path=$STAGING_DIR --skip-themes --skip-plugins --quiet || error 'Unable to drop staging tables.'
    wp option delete staging_environment --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to reset staging environment in production.'
    wp option delete staging_config --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet || error 'Unable to remove global staging config.'
    rm -r $STAGING_DIR --force || error 'Unable to remove staging files.'
    mkdir -p $STAGING_DIR
    echo "<script type='text/javascript'>window.location = '$PRODUCTION_URL';</script>" >$STAGING_DIR/index.php
    clear
    echo \{\"status\":\"success\",\"message\":\"Staging website destroyed.\",\"reload\":\"true\"\}
  fi
}

function move_files {
  FROM="$1"
  TO="$2"

  rm -r $TO/wp-content/themes --force || error 'Unable to remove themes directory.'
  rm -r $TO/wp-content/plugins --force || error 'Unable to remove plugins directory.'

  mkdir -p $TO/wp-content/uploads || error 'Unable to create uploads folder.'
  mkdir -p $TO/wp-content/themes || error 'Unable to create themes folder.'
  mkdir -p $TO/wp-content/plugins || error 'Unable to create plugins folder.'
  rsync -r --exclude=.git $FROM/wp-content/uploads/* $TO/wp-content/uploads || error 'Unable to move uploads folder.'
  rsync -r --exclude=.git $FROM/wp-content/themes/* $TO/wp-content/themes || error 'Unable to move themes folder.'
  rsync -r --exclude=.git $FROM/wp-content/plugins/* $TO/wp-content/plugins || error 'Unable to move plugins folder.'
}

function rewrite_htaccess {
  LOCATION="$1"
  wp eval 'global $wp_rewrite; echo $wp_rewrite->mod_rewrite_rules();' --path=$LOCATION --skip-themes --skip-plugins --quiet >$LOCATION/.htaccess || error 'Unable to create .htaccess file.'
}

function sso_staging {
  if [ -z $1 ]; then
    error 'No user provided.'
  fi
  wp eval 'file_exists( WPMU_PLUGIN_DIR . "/sso.php" ) ? unlink( WPMU_PLUGIN_DIR . "/sso.php" ) : null;' --path=$STAGING_DIR --skip-themes --skip-plugins --quiet
  LINK=$(wp newfold sso --url-only --id=$1 --path=$STAGING_DIR)
  echo \{\"status\":\"success\",\"load_page\":\"$LINK\&redirect=admin.php?page=nfd-staging\"\}
}

function sso_production {
  if [ -z $1 ]; then
    error 'No user provided.'
  fi
  wp eval 'file_exists( WPMU_PLUGIN_DIR . "/sso.php" ) ? unlink( WPMU_PLUGIN_DIR . "/sso.php" ) : null;' --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet
  LINK=$(wp newfold sso --url-only --id=$1 --path=$PRODUCTION_DIR)
  echo \{\"status\":\"success\",\"load_page\":\"$LINK\&redirect=admin.php?page=nfd-staging\"\}
}

function error {
  echo \{\"status\":\"error\",\"message\":\"$1\"\}
  wp transient delete nfd_staging_lock --path="$PRODUCTION_DIR" --skip-themes --skip-plugins --quiet
  exit
}

function lock_check {
  LOCK=$(wp transient get nfd_staging_lock --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)
  if [ -n "$LOCK" ]; then
    error 'Staging action is locked by another command.'
  fi
}

function compatibility_check {
  if ! command -v wp &>/dev/null; then
    echo "WP-CLI is not available."
    exit 1
  fi

  if [ "compat_check" == "$1" ]; then
    echo \{\"status\":\"success\"\}
    exit
  fi
}

PRODUCTION_DIR=$3
STAGING_DIR=$4
PRODUCTION_URL=$5
STAGING_URL=$6
USER_ID=$7
PLUGIN_ID=$8
DB_HOST=$(wp eval 'echo DB_HOST;' --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)
DB_NAME=$(wp eval 'echo DB_NAME;' --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)
DB_USER=$(wp eval 'echo DB_USER;' --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)
DB_PASS=$(wp eval 'echo DB_PASSWORD;' --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)
DB_PREFIX=$(wp eval 'global $wpdb;echo $wpdb->prefix;' --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)
PRODUCTION_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)

if [[ $(pwd) == *"staging"* ]]; then
  CURRENT_DIR=$STAGING_DIR
else
  CURRENT_DIR=$PRODUCTION_DIR
fi

compatibility_check "$1"
#everything must auth.
auth_action $2
lock_check

CONFIG=$(wp option get staging_config --format=json --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet)

wp transient set nfd_staging_lock "true" 120 --path=$PRODUCTION_DIR --skip-themes --skip-plugins --quiet

$1 "$9"

wp transient delete nfd_staging_lock --path="$PRODUCTION_DIR" --skip-themes --skip-plugins --quiet

# $1 is function
# $2 is auth TOKEN
# $3 is production dir
# $4 is staging dir
# $5 is production url
# $6 is staging url
# $7 is current user id
# $8 is plugin id/brand
# $9 is function param 1
