#!/bin/bash

set -euo pipefail  # Safe mode

# Ensure required dependencies are installed
for cmd in kubectl yq jq kubeseal; do
  if ! command -v "$cmd" >/dev/null 2>&1; then
    echo "❌ Error: $cmd is required but not installed."
    exit 1
  fi
done

# Check if a file path is provided, otherwise prompt for it
if [ -z "${1:-}" ]; then
  echo -n "📄 Enter path to the secret file (e.g., secret.yaml): "
  read SECRET_FILE
else
  SECRET_FILE=$1
fi

# Ensure the file exists
if [ ! -f "$SECRET_FILE" ]; then
  echo "❌ Error: File not found: $SECRET_FILE"
  exit 1
fi

# Ensure the file is a Kubernetes Secret
KIND=$(yq eval '.kind' "$SECRET_FILE")
if [ "$KIND" != "Secret" ]; then
  echo "❌ Error: File is not a Kubernetes Secret (found kind: $KIND)"
  exit 1
fi

# Extract namespace and secret name
NAMESPACE=$(yq eval '.metadata.namespace // "default"' "$SECRET_FILE")
SECRET_NAME=$(yq eval '.metadata.name' "$SECRET_FILE")

# Validate extracted values
if [ -z "$SECRET_NAME" ]; then
  echo "❌ Error: Could not extract secret name from $SECRET_FILE"
  exit 1
fi

# Get the current Kubernetes cluster name
CLUSTER_NAME=$(kubectl config current-context)

if ! kubectl version >/dev/null 2>&1; then
  echo "❌ Cannot connect to Kubernetes cluster. Check your context or credentials."
  exit 1
fi

if ! kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" >/dev/null 2>&1; then
  echo "❗ Secret does not exist in cluster."
  changes_detected=true
else
  # Extract and decode Kubernetes secret
  K8S_SECRET_JSON=$(kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o json)
  K8S_SECRET_DATA=$(echo "$K8S_SECRET_JSON" | jq -r '.data | to_entries | map("\(.key) \(.value | @base64d)") | .[]')

  # Extract `stringData` from input file while preserving order
  FILE_SECRET_JSON=$(yq eval -o=json '.stringData // {}' "$SECRET_FILE")
  FILE_SECRET_DATA=$(echo "$FILE_SECRET_JSON" | jq -r 'to_entries | map("\(.key) \(.value|tostring)") | .[]')
  
  # Convert to associative arrays for easier comparison and maintain order
  declare -A k8s_secret_map
  while IFS= read -r line; do
    [[ -z "$line" ]] && continue  # skip empty lines
    key=$(echo "$line" | awk '{print $1}')
    value=$(echo "$line" | cut -d' ' -f2-)
    [[ -z "$key" ]] && continue  # skip lines with empty key
    k8s_secret_map["$key"]="$value"
  done <<< "$K8S_SECRET_DATA"

  declare -A file_secret_map
  declare -a file_secret_keys
  while IFS= read -r line; do
    key=$(echo "$line" | awk '{print $1}')
    value=$(echo "$line" | cut -d' ' -f2-)
    file_secret_map["$key"]="$value"
    file_secret_keys+=("$key")
  done <<< "$FILE_SECRET_DATA"

  RED="\e[31m"
  GREEN="\e[32m"
  YELLOW="\e[33m"
  MAGENTA="\e[35m"
  BLUE="\e[34m"
  RESET="\e[0m"

  # Get terminal width
  COLUMNS=$(tput cols)

  # Function to truncate text with ellipses
  truncate_text() {
    local text="$1"
    local max_length=$((COLUMNS - 20))  # Adjust based on your needs
    if [ ${#text} -gt $max_length ]; then
      echo "${text:0:$max_length}..."
    else
      echo "$text"
    fi
  }

  # Compare and print secrets
  changes_detected=false
  for key in "${file_secret_keys[@]}"; do
    if [[ -v k8s_secret_map["$key"] ]]; then
      if [[ "${file_secret_map[$key]}" != "${k8s_secret_map[$key]}" ]]; then
        changes_detected=true
        break
      fi
    else
      changes_detected=true
      break
    fi
  done

  for key in "${!k8s_secret_map[@]}"; do
    if [[ ! -v file_secret_map["$key"] ]]; then
      changes_detected=true
      break
    fi
  done

  if $changes_detected; then
    echo -e "Comparing secrets...\n"
    for key in "${file_secret_keys[@]}"; do
      if [[ -v k8s_secret_map["$key"] ]]; then
        if [[ "${file_secret_map[$key]}" == "${k8s_secret_map[$key]}" ]]; then
          :
          # truncated_value=$(truncate_text "${file_secret_map[$key]}")
          # printf "• %s: %s\n" "$key" "$truncated_value"
        else
          printf "${YELLOW}🔄 %s:${RESET}\n" "$key"
          printf "  ${MAGENTA}Old:${RESET} %s\n" "${k8s_secret_map[$key]}"
          printf "  ${BLUE}New:${RESET} %s\n" "${file_secret_map[$key]}"
        fi
      else
        printf "${GREEN}➕ %s:${RESET} %s\n" "$key" "${file_secret_map[$key]}"
      fi
    done

    for key in "${!k8s_secret_map[@]}"; do
      if [[ ! -v file_secret_map["$key"] ]]; then
        printf "${RED}➖ %s:${RESET} %s\n" "$key" "${k8s_secret_map[$key]}"
      fi
    done
  else
    echo "😶 No changes detected!"
  fi
fi

# Ask for confirmation to create a sealed secret
echo
echo -e "📂 Input File ($SECRET_FILE)"
echo -e "🌎 K8s Secret ($SECRET_NAME in $NAMESPACE)"
echo -e "🔗 Cluster: $CLUSTER_NAME"
echo "Press Enter to create a Sealed Secret or Ctrl+C to cancel"
read

# Ensure output is a valid YAML
OUTPUT_FILE="${SECRET_FILE/secret.yaml/sealed-secret.yaml}"
kubeseal < "$SECRET_FILE" | yq eval -P > "$OUTPUT_FILE"

if [ $? -eq 0 ]; then
  echo "✅ Sealed secret successfully created: $OUTPUT_FILE (YAML format)"
else
  echo "❌ Error: Failed to create sealed secret."
  exit 1
fi