#!/usr/bin/env bash

# Archive and export iOS app for App Store / TestFlight

set -euxo pipefail

# Ensure xcodebuild uses Xcode.app, not Command Line Tools
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

XCODE_PROJECT_PATH=${1:?Usage: archive_ios.sh <xcode_project_path> <output_path> <team_id> <profile_uuid>}
OUTPUT_PATH=${2:?Missing output path}
TEAM_ID=${3:?Missing team ID}
PROFILE_UUID=${4:?Missing provisioning profile UUID}

ARCHIVE_PATH="$OUTPUT_PATH/eagle0.xcarchive"
EXPORT_PATH="$OUTPUT_PATH"

echo "Archiving iOS app..."
echo "  Xcode project: $XCODE_PROJECT_PATH"
echo "  Archive path: $ARCHIVE_PATH"
echo "  Team ID: $TEAM_ID"

mkdir -p "$OUTPUT_PATH"

# Find the .xcodeproj file
XCODEPROJ=$(find "$XCODE_PROJECT_PATH" -name "*.xcodeproj" -maxdepth 1 | head -1)
if [ -z "$XCODEPROJ" ]; then
    echo "Error: No .xcodeproj found in $XCODE_PROJECT_PATH"
    exit 1
fi

echo "Found Xcode project: $XCODEPROJ"

# Ensure export compliance key is set in Info.plist
# This bypasses the "Missing Compliance" prompt in App Store Connect.
# Set here rather than relying solely on Unity's DeepLinkPostProcessor,
# which depends on UNITY_IOS being defined at script compilation time.
INFO_PLIST="$XCODE_PROJECT_PATH/Info.plist"
if [ -f "$INFO_PLIST" ]; then
    /usr/libexec/PlistBuddy -c "Set :ITSAppUsesNonExemptEncryption false" "$INFO_PLIST" 2>/dev/null \
        || /usr/libexec/PlistBuddy -c "Add :ITSAppUsesNonExemptEncryption bool false" "$INFO_PLIST"
    echo "Set ITSAppUsesNonExemptEncryption=false in Info.plist"
fi

# Unity always generates "Unity-iPhone" as the main app scheme
SCHEME="Unity-iPhone"
echo "Using scheme: $SCHEME"

# Xcode can be upgraded on a self-hosted runner before its matching iOS platform
# component is installed. In that state, xcrun may exist but the generic iOS
# destination is ineligible, and archive fails with exit code 70. Probe the exact
# destination used below and repair the Xcode installation before starting the
# expensive archive.
if ! xcodebuild \
    -project "$XCODEPROJ" \
    -scheme "$SCHEME" \
    -showBuildSettings \
    -destination "generic/platform=iOS" >/dev/null; then
    echo "The generic iOS destination is unavailable; installing Xcode's iOS platform..."

    if ! xcodebuild -checkFirstLaunchStatus; then
        echo "Completing pending Xcode first-launch setup..."
        xcodebuild -runFirstLaunch
    fi

    xcodebuild -downloadPlatform iOS
fi

echo "Installed Xcode SDKs:"
xcodebuild -showsdks
IOS_SDK_PATH=$(xcrun --sdk iphoneos --show-sdk-path)
if [ ! -d "$IOS_SDK_PATH" ]; then
    echo "Error: Xcode reported an invalid iOS SDK path: $IOS_SDK_PATH"
    exit 1
fi
echo "Using iOS SDK: $IOS_SDK_PATH"

if ! xcodebuild \
    -project "$XCODEPROJ" \
    -scheme "$SCHEME" \
    -showBuildSettings \
    -destination "generic/platform=iOS" >/dev/null; then
    echo "Error: The generic iOS destination is still unavailable after platform setup."
    xcodebuild -project "$XCODEPROJ" -scheme "$SCHEME" -showdestinations || true
    exit 1
fi

# Archive without signing - we'll sign during export
# This avoids issues with provisioning profiles on framework targets
xcodebuild archive \
    -project "$XCODEPROJ" \
    -scheme "$SCHEME" \
    -archivePath "$ARCHIVE_PATH" \
    -destination "generic/platform=iOS" \
    CODE_SIGN_IDENTITY="-" \
    CODE_SIGNING_REQUIRED=NO \
    CODE_SIGNING_ALLOWED=NO

echo "Archive complete: $ARCHIVE_PATH"

# Create export options plist
# Signing happens here, not during archive
EXPORT_OPTIONS_PLIST="$OUTPUT_PATH/ExportOptions.plist"
cat > "$EXPORT_OPTIONS_PLIST" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>app-store-connect</string>
    <key>teamID</key>
    <string>$TEAM_ID</string>
    <key>uploadSymbols</key>
    <true/>
    <key>signingStyle</key>
    <string>manual</string>
    <key>signingCertificate</key>
    <string>Apple Distribution: Daniel Crosby (UWJ88DX8WQ)</string>
    <key>provisioningProfiles</key>
    <dict>
        <key>net.eagle0.eagle</key>
        <string>$PROFILE_UUID</string>
    </dict>
</dict>
</plist>
EOF

echo "Exporting IPA..."

# Restore keychain search list before export.
# xcodebuild archive can reset the user keychain search list during long
# builds, dropping the temporary CI keychain that holds the signing cert.
# Re-add it here so xcodebuild -exportArchive can find the certificate.
if [ -n "${KEYCHAIN_NAME:-}" ]; then
    echo "Restoring keychain search list (adding $KEYCHAIN_NAME)"
    security list-keychains -d user -s "$KEYCHAIN_NAME" login.keychain
    security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
fi

# Debug: List available keychains and signing identities
echo "=== Debug: Available keychains ==="
security list-keychains -d user
echo "=== Debug: Available signing identities ==="
security find-identity -v -p codesigning
echo "=== Debug: Export options plist ==="
cat "$EXPORT_OPTIONS_PLIST"
echo "=== End debug ==="

# Export IPA with App Store Connect API key authentication.
# Without the API key, xcodebuild falls back to the Xcode-Token in the
# keychain, which expires periodically and breaks headless CI builds.
EXPORT_AUTH_ARGS=()
if [ -n "${APP_STORE_CONNECT_API_KEY_PATH:-}" ] && [ -n "${APP_STORE_CONNECT_API_KEY_ID:-}" ] && [ -n "${APP_STORE_CONNECT_API_ISSUER_ID:-}" ]; then
    echo "Using App Store Connect API key for export authentication"
    EXPORT_AUTH_ARGS=(
        -authenticationKeyPath "$APP_STORE_CONNECT_API_KEY_PATH"
        -authenticationKeyID "$APP_STORE_CONNECT_API_KEY_ID"
        -authenticationKeyIssuerID "$APP_STORE_CONNECT_API_ISSUER_ID"
    )
fi

xcodebuild -exportArchive \
    -archivePath "$ARCHIVE_PATH" \
    -exportPath "$EXPORT_PATH" \
    -exportOptionsPlist "$EXPORT_OPTIONS_PLIST" \
    "${EXPORT_AUTH_ARGS[@]}"

# Find and rename the IPA to a consistent name
IPA_FILE=$(find "$EXPORT_PATH" -name "*.ipa" | head -1)
if [ -n "$IPA_FILE" ] && [ "$IPA_FILE" != "$EXPORT_PATH/eagle0.ipa" ]; then
    mv "$IPA_FILE" "$EXPORT_PATH/eagle0.ipa"
fi

echo "Export complete: $EXPORT_PATH/eagle0.ipa"
ls -la "$EXPORT_PATH"

# Clean up DerivedData for Unity-iPhone builds.
# Each build creates a new ~3.6GB folder (Unity-iPhone-<random>) that
# accumulates and wastes disk space on the build runner.
echo "Cleaning up Unity-iPhone DerivedData..."
find ~/Library/Developer/Xcode/DerivedData -maxdepth 1 -name 'Unity-iPhone-*' -type d -exec rm -rf {} + 2>/dev/null || true
