#!/bin/bash

# -----------------------------------------------------------------------------
# Script Name: activation_code_setup
#
# Description:
# This script sets up the activation environment by performing various tasks,
# such as setting system banners, icons, and metadata based on activation assets 
# and configurations. The script ensures that activation settings are applied only 
# once by using a setup flag.
#
# Key Features:
# - Verifies if the activation directory and setup flag exist before proceeding.
# - Updates partner logos, banners, and other visual assets in the system.
# - Configures system display settings (e.g., theme, colors) based on activation JSON.
# - Sets server identification (name, model, and description) if not already configured.
# - Creates a setup flag to prevent re-execution of tasks.
#
# Prerequisites:
# - Ensure that the activation directory exists at "/boot/config/activation".
# - The script requires `jq` for JSON parsing. Install it if not already available.
#
# Usage:
# 1. Run the script normally:
#    ./activation_code_setup
#
# 2. Run the script with debug statements:
#    ./activation_code_setup --debug
#
# Options:
# --debug    Enables debug mode to display additional information.
#
# Files Used:
# - Activation JSON: A configuration file with `.activationcode` extension, located in
#   the activation directory.
# - Partner assets: Logo, banner, and case model located in the "assets" subdirectory
#   of the activation directory.
# - System configuration files such as:
#   - `/boot/config/plugins/dynamix/dynamix.cfg`
#   - `/boot/config/plugins/dynamix/case-model.cfg`
#   - `/boot/config/ident.cfg`
# - System state file: `/usr/local/emhttp/state/var.ini`
#
# Notes:
# - Existing configurations will not be overwritten unless required (e.g., no backup exists).
# - Any errors during setup will print warnings but allow the script to continue.
#
# -----------------------------------------------------------------------------

# Default flags
DEBUG_MODE=false
# Check for flags
for arg in "$@"; do
  case $arg in
    --debug)
      DEBUG_MODE=true
      ;;
    *)
      # You can optionally handle other arguments if needed
      ;;
  esac
done

# Debug function
debug_echo() {
  if [[ $DEBUG_MODE == true ]]; then
    echo "[DEBUG] [activation_code_setup]: $1"
  fi
}

ACTIVATION_DIR="/boot/config/activation"

debug_echo "Checking for activation directory at $ACTIVATION_DIR"

if [[ -d "$ACTIVATION_DIR" ]]; then
  debug_echo "Activation directory found"
  ACTIVATION_SETUP_FLAG="$ACTIVATION_DIR/.done"
  ACTIVATION_JSON_EXTENSION=".activationcode"
  # get the first file in the dir that matches the extension, later parsed as JSON for specific values
  ACTIVATION_JSON=$(find "$ACTIVATION_DIR" -maxdepth 1 -type f -name "*$ACTIVATION_JSON_EXTENSION" | head -n 1)
  PARTNER_ASSETS_DIR="$ACTIVATION_DIR/assets"
  WEBGUI_IMAGES_DIR="/usr/local/emhttp/webGui/images"

  ACTIVATION_JSON_VALID=false
  if [[ -f "$ACTIVATION_JSON" ]]; then
    debug_echo "Activation JSON found at $ACTIVATION_JSON, validating..."
    # Validate the JSON file
    if jq empty "$ACTIVATION_JSON" 2>/dev/null; then
      ACTIVATION_JSON_VALID=true
      debug_echo "Activation JSON is valid"
    else
      echo "⚠️ Warning: Activation JSON is not valid, skipping setup"
    fi
  fi

  if [[ "$ACTIVATION_JSON_VALID" == true ]]; then
    debug_echo "Activation JSON is valid, proceeding with setup"
    # create the setup flag file to prevent re-running this setup
    touch "$ACTIVATION_SETUP_FLAG"

    # Auth Request Modification move into the Unraid API
    # @todo - Move the remaining modifications into the Unraid API
    # Inject the welcome modal into the .set-password.php file
    WELCOME_MODAL_INJECT_FILE="/usr/local/emhttp/plugins/dynamix/include/.set-password.php"
    # shellcheck disable=SC2016
    WELCOME_MODAL_INJECT_STRING='<?include "$docroot/plugins/dynamix.my.servers/include/welcome-modal.php"?>'

    if grep -q "</body>" "$WELCOME_MODAL_INJECT_FILE"; then
      cp "$WELCOME_MODAL_INJECT_FILE" "${WELCOME_MODAL_INJECT_FILE}.bak"
      debug_echo "Backup of $WELCOME_MODAL_INJECT_FILE created at ${WELCOME_MODAL_INJECT_FILE}.bak"

      awk -v inject="$WELCOME_MODAL_INJECT_STRING" '
        /<\/body>/ {
          print inject
        }
        { print }
      ' "$WELCOME_MODAL_INJECT_FILE" > "${WELCOME_MODAL_INJECT_FILE}.tmp"

      mv "${WELCOME_MODAL_INJECT_FILE}.tmp" "$WELCOME_MODAL_INJECT_FILE"
      debug_echo "Welcome modal injected into $WELCOME_MODAL_INJECT_FILE"
    else
      debug_echo "Failed to inject welcome modal into $WELCOME_MODAL_INJECT_FILE"
    fi

    # copy the logo into a location that the webgui can access
    PARTNER_LOGO="$PARTNER_ASSETS_DIR/logo.svg"
    if [[ -f "$PARTNER_LOGO" ]]; then
      debug_echo "Partner logo found"
      # symlink the file to the correct destination with the correct extension
      LINK_DEST="$WEBGUI_IMAGES_DIR/partner-logo.svg"
      ln -sf "$PARTNER_LOGO" "$LINK_DEST"
      debug_echo "Partner logo symlinked to $LINK_DEST"
    else
      debug_echo "No partner logo found"
    fi

    # if partner banner exists and there's not a webgui banner backup file that exists on the system
    # then backup the original banner and replace the original banner with the included partner banner
    PARTNER_BANNER="$PARTNER_ASSETS_DIR/banner.png"
    WEBGUI_BANNER_OG="$WEBGUI_IMAGES_DIR/banner.png"
    WEBGUI_BANNER_BK="$WEBGUI_BANNER_OG-"

    # On uninstall of the PLG the default banner is reverted. So we won't rely on the setup flag. Instead whether the backup file doesn't exist.
    debug_echo "Checking for partner banner at $PARTNER_BANNER and backup banner at $WEBGUI_BANNER_BK"
    if [[ -f "$PARTNER_BANNER" && ! -f "$WEBGUI_BANNER_BK" ]]; then
      debug_echo "Partner banner found at $PARTNER_BANNER"
      cp -f "$WEBGUI_BANNER_OG" "$WEBGUI_BANNER_BK" 2>/dev/null
      if [[ $? -ne 0 ]]; then
        echo "⚠️ Warning: Failed to back up the original banner."
      else
        debug_echo "Original banner backed up to $WEBGUI_BANNER_BK"
      fi
      cp -f "$PARTNER_BANNER" "$WEBGUI_BANNER_OG" 2>/dev/null
      if [[ $? -ne 0 ]]; then
        echo "⚠️ Warning: Failed to replace the original banner with the partner banner."
      else
        debug_echo "Partner banner replaced the original banner"
      fi
    else
      debug_echo "Skipping partner banner setup"
    fi

    #
    # Inject the partner logo in DefaultPageLayout
    #
    DEFAULT_PAGE_LAYOUT_FILE="/usr/local/emhttp/plugins/dynamix/include/DefaultPageLayout.php"
    # shellcheck disable=SC2016
    WEBGUI_LOGO_STRING_FIND='<a href="https://unraid.net" target="_blank"><?readfile("$docroot/webGui/images/UN-logotype-gradient.svg")?></a>'
    # shellcheck disable=SC2016
    PARTNER_LOGO_STRING_REPLACE='<?include "$docroot/plugins/dynamix.my.servers/include/partner-logo.php"?>'
    # if a backup of the original layout doesn't already exist, then we'll create it.
    if [[ ! -f "${DEFAULT_PAGE_LAYOUT_FILE}-" ]]; then
      cp -f "$DEFAULT_PAGE_LAYOUT_FILE" "${DEFAULT_PAGE_LAYOUT_FILE}-"
      debug_echo "Backup of $DEFAULT_PAGE_LAYOUT_FILE created at ${DEFAULT_PAGE_LAYOUT_FILE}-"
    fi

    debug_echo "Injecting partner logo into $DEFAULT_PAGE_LAYOUT_FILE"
    sed -i "s|$WEBGUI_LOGO_STRING_FIND|$PARTNER_LOGO_STRING_REPLACE|" "$DEFAULT_PAGE_LAYOUT_FILE"

    if [[ $? -eq 0 ]]; then
      debug_echo "Injected partner logo into $DEFAULT_PAGE_LAYOUT_FILE"
    else
      debug_echo "Failed to inject partner logo into $DEFAULT_PAGE_LAYOUT_FILE, awk error"
    fi

    # Set the display settings, if we haven't done it once already
    if ! grep -q "display" "$ACTIVATION_SETUP_FLAG"; then
      debug_echo "Checking for display settings in the activation JSON"
      HEADER_TEXT_COLOR=$(jq -r '.header // empty' "$ACTIVATION_JSON" 2>/dev/null || true)
      HEADER_META_COLOR=$(jq -r '.headermetacolor // empty' "$ACTIVATION_JSON" 2>/dev/null || true)
      HEADER_BG_COLOR=$(jq -r '.background // empty' "$ACTIVATION_JSON" 2>/dev/null || true)
      HEADER_SHOW_BANNER_GRADIENT=$(jq -r '.showBannerGradient // empty' "$ACTIVATION_JSON" 2>/dev/null || true)
      WEBGUI_THEME=$(jq -r '.theme // empty' "$ACTIVATION_JSON" 2>/dev/null || true)

      # Initialize array for parameters
      declare -A DISPLAY_PARAMS

      # Check if variables have values and add them to the array, while stripping any leading # from the color values b/c the settings config doesn't use them
      [[ -n $HEADER_TEXT_COLOR ]] && DISPLAY_PARAMS["header"]=${HEADER_TEXT_COLOR//\#/}
      [[ -n $HEADER_META_COLOR ]] && DISPLAY_PARAMS["headermetacolor"]=${HEADER_META_COLOR//\#/}
      [[ -n $HEADER_BG_COLOR ]] && DISPLAY_PARAMS["background"]=${HEADER_BG_COLOR//\#/}
      [[ -n $HEADER_SHOW_BANNER_GRADIENT ]] && DISPLAY_PARAMS["showBannerGradient"]=$HEADER_SHOW_BANNER_GRADIENT
      [[ -n $WEBGUI_THEME ]] && DISPLAY_PARAMS["theme"]=$WEBGUI_THEME
      DISPLAY_PARAMS["banner"]="image"

      debug_echo "Display settings found:"
      for key in "${!DISPLAY_PARAMS[@]}"; do
        debug_echo "$key: ${DISPLAY_PARAMS[$key]}"
      done

      CONFIG_FILE="/boot/config/plugins/dynamix/dynamix.cfg"
      CONFIG_SECTION="display"
      debug_echo "Updating display settings in $CONFIG_FILE"
      # Iterate over the DISPLAY_PARAMS array and update the config file
      for key in "${!DISPLAY_PARAMS[@]}"; do
        value=${DISPLAY_PARAMS[$key]}
        debug_echo "Setting $key to $value"

        awk -v section="$CONFIG_SECTION" -v key="$key" -v value="$value" '
        BEGIN { in_section = 0; key_found = 0 }
        /^\[.*\]$/ { 
          if (in_section && !key_found) {
            # Append the key-value pair before leaving the section
            print key "=" "\"" value "\""
          }
          in_section = ($0 == "[" section "]")
          key_found = 0
        }
        {
          if (in_section && $0 ~ "^" key "=") {
            print key "=" "\"" value "\""
            key_found = 1
            next
          }
        }
        { print }
        END {
          if (in_section && !key_found) {
            # Append key-value pair at the end of the section if not found
            print key "=" "\"" value "\""
          }
        }' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
      done

      # Add what changed to the .done flag file
      echo "display" >> "$ACTIVATION_SETUP_FLAG"
      debug_echo "Display settings updated"
    else
      debug_echo "Skipping display settings setup, flag already set"
    fi

    # Set the case model icon, if we haven't done it once already
    if ! grep -q "case" "$ACTIVATION_SETUP_FLAG"; then
      debug_echo "Check for case model icon setup"
      CASE_MODEL_CFG="/boot/config/plugins/dynamix/case-model.cfg"
      CUSTOM_CASE_FILE_NAME="case-model.png"
      # if the system has a custom icon already set, we need to skip this step
      # First preference is to use a custom icon, if it exists in the activation/assets dir
      # Second preference is to use an included icon with the system that's been specified in the activation json
      CURRENT_CASE_MODEL=$(cat $CASE_MODEL_CFG 2>/dev/null || true)
      debug_echo "Current case model icon: $CURRENT_CASE_MODEL"
      # If CURRENT_CASE_MODEL === "case-model.png" then a custom icon has already been set and we should skip this step
      if [[ -n "$CURRENT_CASE_MODEL" && "$CURRENT_CASE_MODEL" != "$CUSTOM_CASE_FILE_NAME" ]]; then
        PARTNER_CASE_MODEL="$PARTNER_ASSETS_DIR/$CUSTOM_CASE_FILE_NAME" # for custom image
        PARTNER_CASE_ICON=$(jq -r '.caseIcon // empty' "$ACTIVATION_JSON" 2>/dev/null || true); # for included with system icon
        debug_echo "Partner case model icon: $PARTNER_CASE_MODEL"
        if [[ -f "$PARTNER_CASE_MODEL" ]]; then
          # First remove any existing symlink or file
          rm -f "$WEBGUI_IMAGES_DIR/$CUSTOM_CASE_FILE_NAME"
          cp -f "$PARTNER_CASE_MODEL" "$WEBGUI_IMAGES_DIR/$CUSTOM_CASE_FILE_NAME"
          if [[ $? -ne 0 ]]; then
            echo "⚠️ Warning: Failed to replace the original case model icon with the custom icon."
          else
            echo -n "$CUSTOM_CASE_FILE_NAME" > $CASE_MODEL_CFG # set the custom icon in the config file
            echo "case: $CUSTOM_CASE_FILE_NAME" >> "$ACTIVATION_SETUP_FLAG" # add what changed to the .done flag file
            debug_echo "Custom case model set"
          fi
        elif [[ -n "$PARTNER_CASE_ICON" ]]; then
          echo -n "$PARTNER_CASE_ICON" > $CASE_MODEL_CFG # set the parsed icon name in the config file
          echo "case: $PARTNER_CASE_ICON" >> "$ACTIVATION_SETUP_FLAG" # add what changed to the .done flag file
          debug_echo "Case model set to $PARTNER_CASE_ICON"
        fi
      else
        echo "case: skipped, already custom" >> "$ACTIVATION_SETUP_FLAG" # add what changed to the .done flag file
        debug_echo "Skipping case model setup, already set as custom icon"
      fi
    else
      debug_echo "Skipping case model setup, flag already set"
    fi

    # Set the server name, model, and description if we haven't already done it once
    if ! grep -q "identity" "$ACTIVATION_SETUP_FLAG"; then
      debug_echo "Checking server identification"
      VAR_INI="/usr/local/emhttp/state/var.ini"
      # If there's not a set system model or comment (aka description), we'll attempt to set it from activation json
      CURRENT_NAME=$(awk -F "=" '/NAME/ {print $2}' $VAR_INI 2>/dev/null | tr -d '"')
      CURRENT_SYS_MODEL=$(awk -F "=" '/SYS_MODEL/ {print $2}' $VAR_INI 2>/dev/null | tr -d '"')
      CURRENT_COMMENT=$(awk -F "=" '/COMMENT/ {print $2}' $VAR_INI 2>/dev/null | tr -d '"')

      if [[ -z "$CURRENT_SYS_MODEL" || -z "$CURRENT_COMMENT" || "$CURRENT_COMMENT" == "Media server" || "$CURRENT_NAME" == "Tower" ]]; then
        PARTNER_SERVER_NAME=$(jq -r '.serverName // empty' "$ACTIVATION_JSON" 2>/dev/null || true)
        PARTNER_SYS_MODEL=$(jq -r '.sysModel // empty' "$ACTIVATION_JSON" 2>/dev/null || true)
        PARTNER_COMMENT=$(jq -r '.comment // empty' "$ACTIVATION_JSON" 2>/dev/null || true)
        # Sanitize strings to remove quotes and backslashes
        PARTNER_SERVER_NAME=${PARTNER_SERVER_NAME//["\\"]/}
        PARTNER_SYS_MODEL=${PARTNER_SYS_MODEL//["\\"]/}
        PARTNER_COMMENT=${PARTNER_COMMENT//["\\"]/}

        debug_echo "Partner server name: $PARTNER_SERVER_NAME"
        debug_echo "Partner system model: $PARTNER_SYS_MODEL"
        debug_echo "Partner comment: $PARTNER_COMMENT"

        declare -A IDENT_PARAMS
        if [[ -n "$PARTNER_SERVER_NAME" ]]; then
          IDENT_PARAMS["NAME"]=$PARTNER_SERVER_NAME
        fi
        if [[ -n "$PARTNER_SYS_MODEL" ]]; then
          IDENT_PARAMS["SYS_MODEL"]=$PARTNER_SYS_MODEL
        fi
        if [[ -n "$PARTNER_COMMENT" ]]; then
          IDENT_PARAMS["COMMENT"]=$PARTNER_COMMENT
        fi

        if [[ ${#IDENT_PARAMS[@]} -gt 0 ]]; then
          echo "⏳ Please wait...updating system identification"

          # @todo - This may not be needed, double check if emhttp is updating the ident.cfg file
          for key in "${!IDENT_PARAMS[@]}"; do
            value=${IDENT_PARAMS[$key]}
            CONFIG_FILE="/boot/config/ident.cfg"
            debug_echo "Setting $key to $value in $CONFIG_FILE"

            # Use awk to update or append the key-value pair
            awk -v key="$key" -v value="$value" '
            BEGIN { key_found = 0 }
            {
              if ($0 ~ "^" key "=") {
                print key "=" "\"" value "\""
                key_found = 1
              } else {
                print $0
              }
            }
            END {
              if (!key_found) {
                print key "=" "\"" value "\""
              }
            }' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
          done

          EM_CMD=$(IFS="&"; for key in "${!IDENT_PARAMS[@]}"; do echo "$key=${IDENT_PARAMS[$key]}"; done | paste -sd '&')

          debug_echo "updating system identification for emhttp"

          emcmd "$EM_CMD&changeNames=Apply"

          debug_echo "System identification updated"
          echo "✅ Identification updated: $EM_CMD"

          # Add what changed to the .done flag file
          echo "identity: $EM_CMD" >> "$ACTIVATION_SETUP_FLAG"
        fi
      fi
    else
      debug_echo "Skipping server identification setup, flag already set"
    fi

    debug_echo "Activation setup complete"
  fi
else
  debug_echo "Activation directory not found"
fi
