#
# pendo_spm_fix.rb
# Fixes Pendo.framework code signing and embedding for React Native apps using SPM
# See: https://github.com/pendo-io/pendo-mobile-sdk
#
# REQUIRED: Add this to your ios/Podfile:
#
#   require_relative '../node_modules/react-native-pendo-sdk/scripts/pendo_spm_fix'
#
#   # ... target block ...
#
#   post_install do |installer|
#     # ... other post_install code (like react_native_post_install) ...
#
#     # Fix Pendo SPM framework signing and embedding
#     pendo_fix_spm_signing(installer)
#   end
#
# Options:
#   pendo_fix_spm_signing(installer, app_target_name: 'MyAppName')
#   - Use app_target_name if you have multiple targets or non-standard naming
#

def pendo_fix_spm_signing(installer, app_target_name: nil)
  # Find the main project from the installer's aggregate targets to avoid CocoaPods overwriting changes
  main_project = nil
  installer.aggregate_targets.each do |target|
    if target.user_project
      main_project = target.user_project
      break
    end
  end

  if main_project.nil?
    # Fallback to opening the project manually if not found in aggregate targets
    main_project_path = File.join(installer.sandbox.root.parent, "#{installer.sandbox.root.parent.basename}.xcodeproj")

    # If the default path doesn't exist, try to find any .xcodeproj
    unless File.exist?(main_project_path)
      xcodeproj_files = Dir.glob(File.join(installer.sandbox.root.parent, "*.xcodeproj"))
      main_project_path = xcodeproj_files.first if xcodeproj_files.any?
    end

    unless main_project_path && File.exist?(main_project_path)
      Pod::UI.warn "[Pendo] Could not find main Xcode project. SPM framework embedding must be configured manually."
      return
    end

    main_project = Xcodeproj::Project.open(main_project_path)
  end

  # Find the app target
  app_target = if app_target_name
    main_project.targets.find { |t| t.name == app_target_name }
  else
    # Find first application target
    main_project.targets.find { |t| t.product_type == "com.apple.product-type.application" }
  end

  unless app_target
    Pod::UI.warn "[Pendo] Could not find app target. SPM framework embedding must be configured manually."
    return
  end

  Pod::UI.puts "[Pendo] Configuring SPM framework embedding and signing for target: #{app_target.name}"

  # Remove old/duplicate Pendo embed phases
  old_phase_names = [
    'Embed SPM Frameworks (Pendo)',
    '[Pendo] Embed & Sign SPM Frameworks'
  ]

  phases_to_remove = app_target.shell_script_build_phases.select { |p| old_phase_names.include?(p.name) }
  phases_to_remove.each do |phase|
    app_target.build_phases.delete(phase)
    Pod::UI.puts "[Pendo] Removed old build phase: #{phase.name}"
  end

  # Create new consolidated build phase
  embed_phase_name = '[Pendo] Embed & Sign SPM Frameworks'

  phase = app_target.new_shell_script_build_phase(embed_phase_name)
  phase.shell_script = <<~'SCRIPT'
    set -euo pipefail

    # Embed and sign SPM framework (Pendo)
    # This phase MUST run LAST, after all other framework embedding

    FRAMEWORKS_DIR="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}"
    mkdir -p "$FRAMEWORKS_DIR"

    sign_framework() {
      local framework_path="$1"
      local framework_name=$(basename "$framework_path")

      if [ ! -d "$framework_path" ]; then
        echo "warning: $framework_name not found at $framework_path, skipping"
        return 0
      fi

      echo "[Pendo] Processing $framework_name..."

      # Copy to app bundle
      rsync -av --delete "$framework_path" "$FRAMEWORKS_DIR/"

      local dest_framework="$FRAMEWORKS_DIR/$framework_name"

      # Sign if required (physical device builds only)
      if [ "${CODE_SIGNING_REQUIRED:-NO}" = "YES" ] && [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" ]; then
        echo "[Pendo] Signing $framework_name with identity: ${EXPANDED_CODE_SIGN_IDENTITY}"

        # Make framework writable (rsync preserves read-only from source)
        chmod -R u+w "$dest_framework"

        # Strip existing signature and re-sign with app's identity
        # This is required for pre-signed xcframeworks from SPM
        /usr/bin/codesign --force --deep --sign "${EXPANDED_CODE_SIGN_IDENTITY}" \
          --timestamp=none \
          "$dest_framework"

        echo "[Pendo] Successfully signed $framework_name"
      else
        echo "[Pendo] Code signing not required (simulator build)"
      fi
    }

    # Sign Pendo.framework from SPM
    sign_framework "${BUILT_PRODUCTS_DIR}/Pendo.framework"

    echo "[Pendo] SPM framework embedding complete"
  SCRIPT

  # Move to the very end of build phases (after all CocoaPods phases)
  app_target.build_phases.move(phase, app_target.build_phases.count - 1)

  main_project.save
  Pod::UI.puts "[Pendo] Added '#{embed_phase_name}' build phase (placed last for proper signing)"
end
