#!/bin/bash

# ProofMode iOS Setup Script
# This script prepares everything needed to build and run the iOS example app

set -e

echo "🍎 Setting up ProofMode iOS Development"
echo "========================================="

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Function to print colored output
print_status() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Check if we're on macOS
if [[ "$OSTYPE" != "darwin"* ]]; then
    print_warning "This script is designed for macOS. On other platforms, it will prepare files but cannot build."
    MACOS=false
else
    MACOS=true
fi

# Check prerequisites
print_status "Checking prerequisites..."

# Check Rust
if ! command -v cargo &> /dev/null; then
    print_error "Rust/Cargo not found. Please install Rust from https://rustup.rs/"
    exit 1
fi

# Check cargo-make
if ! command -v cargo-make &> /dev/null; then
    print_status "Installing cargo-make..."
    cargo install cargo-make
fi

if $MACOS; then
    # Check Xcode
    if ! command -v xcodebuild &> /dev/null; then
        print_error "Xcode not found. Please install Xcode from the App Store."
        exit 1
    fi

    # Check Xcode command line tools
    if ! xcode-select -p &> /dev/null; then
        print_error "Xcode command line tools not found. Please run: xcode-select --install"
        exit 1
    fi
fi

print_success "Prerequisites check completed"

# Install iOS targets
print_status "Installing iOS targets..."
rustup target add aarch64-apple-ios
rustup target add x86_64-apple-ios  
rustup target add aarch64-apple-ios-sim

print_success "iOS targets installed"

# Create directories
print_status "Creating directory structure..."
mkdir -p target/ios
mkdir -p bindings/ios
mkdir -p scripts/ios

print_success "Directory structure created"

if $MACOS; then
    # Build for iOS (this will only work on macOS)
    print_status "Building Rust library for iOS targets..."
    
    echo "Building for iOS device (ARM64)..."
    if cargo build --target aarch64-apple-ios --features uniffi --release; then
        print_success "iOS device build completed"
    else
        print_error "Failed to build for iOS device"
        exit 1
    fi
    
    echo "Building for iOS simulator (x86_64)..."
    if cargo build --target x86_64-apple-ios --features uniffi --release; then
        print_success "iOS simulator (Intel) build completed"
    else
        print_error "Failed to build for iOS simulator (Intel)"
        exit 1
    fi
    
    echo "Building for iOS simulator (ARM64)..."
    if cargo build --target aarch64-apple-ios-sim --features uniffi --release; then
        print_success "iOS simulator (Apple Silicon) build completed"
    else
        print_error "Failed to build for iOS simulator (Apple Silicon)"
        exit 1
    fi
    
    # Generate UniFFI bindings
    print_status "Generating Swift bindings..."
    if cargo make generate-ios-bindings; then
        print_success "Swift bindings generated"
    else
        print_warning "Swift bindings generation failed, creating mock bindings"
        # Create mock Swift bindings for demo
        mkdir -p bindings/ios
        cat > bindings/ios/ProofMode.swift << 'EOF'
// Mock ProofMode Swift bindings
// Replace with actual UniFFI generated bindings

import Foundation

public class ProofMode {
    public init() {}
    
    public func generateProof(data: Data, metadata: [String: String]?) -> String {
        return "mock-proof-hash-\(Date().timeIntervalSince1970)"
    }
    
    public func verifyProof(hash: String) -> Bool {
        return true
    }
}
EOF
    fi
    
    # Create XCFramework
    print_status "Creating XCFramework..."
    if cargo make create-xcframework; then
        print_success "XCFramework created"
    else
        print_warning "XCFramework creation failed"
    fi
    
else
    print_warning "Not on macOS - skipping native builds"
    print_status "Creating mock bindings for reference..."
    
    # Create mock Swift bindings for reference
    mkdir -p bindings/ios
    cat > bindings/ios/ProofMode.swift << 'EOF'
// Mock ProofMode Swift bindings for non-macOS development
// These are placeholder implementations
// On macOS, run this script to generate actual UniFFI bindings

import Foundation

public struct LocationInfo {
    public let latitude: Double
    public let longitude: Double
    public let altitude: Double?
    public let accuracy: Double?
    public let timestamp: Date
    
    public init(latitude: Double, longitude: Double, altitude: Double?, accuracy: Double?, timestamp: Date) {
        self.latitude = latitude
        self.longitude = longitude
        self.altitude = altitude
        self.accuracy = accuracy
        self.timestamp = timestamp
    }
}

public struct DeviceInfo {
    public let manufacturer: String
    public let model: String
    public let osVersion: String
    public let deviceId: String
    public let imei: String?
    
    public init(manufacturer: String, model: String, osVersion: String, deviceId: String, imei: String?) {
        self.manufacturer = manufacturer
        self.model = model
        self.osVersion = osVersion
        self.deviceId = deviceId
        self.imei = imei
    }
}

public struct NetworkInfo {
    public let networkType: String
    public let carrier: String?
    public let cellTowerId: String?
    public let wifiSsid: String?
    
    public init(networkType: String, carrier: String?, cellTowerId: String?, wifiSsid: String?) {
        self.networkType = networkType
        self.carrier = carrier
        self.cellTowerId = cellTowerId
        self.wifiSsid = wifiSsid
    }
}

public protocol LocationProvider {
    func getLocation() -> LocationInfo?
}

public protocol DeviceInfoProvider {
    func getDeviceInfo() -> DeviceInfo?
}

public protocol NetworkInfoProvider {
    func getNetworkInfo() -> NetworkInfo?
}

public enum ProofModeError: Error {
    case io(String)
    case pgpError(String)
    case storageError(String)
    case serializationError(String)
    case notInitialized(String)
    case invalidMediaData(String)
    case proofNotFound(String)
    case checkError(String)
}

public class ProofMode {
    private var initialized = false
    
    public init() {}
    
    public func initialize(storagePath: String, email: String, passphrase: String) throws {
        // Mock initialization
        initialized = true
    }
    
    public func generateProof(mediaData: Data, metadata: [String: String]?) throws -> String {
        guard initialized else {
            throw ProofModeError.notInitialized("ProofMode not initialized")
        }
        return "mock-proof-hash-\(Date().timeIntervalSince1970)"
    }
    
    public func generateProofFromFile(filePath: String, metadata: [String: String]?) throws -> String {
        guard initialized else {
            throw ProofModeError.notInitialized("ProofMode not initialized")
        }
        return "mock-proof-hash-\(Date().timeIntervalSince1970)"
    }
    
    public func verifyProof(hash: String) throws -> Bool {
        guard initialized else {
            throw ProofModeError.notInitialized("ProofMode not initialized")
        }
        return true
    }
    
    public func getPublicKey() -> String {
        return "-----BEGIN PGP PUBLIC KEY BLOCK-----\n[Mock PGP Public Key]\n-----END PGP PUBLIC KEY BLOCK-----"
    }
}
EOF
fi

# Create iOS build script
print_status "Creating iOS-specific build scripts..."

cat > scripts/ios/build-framework.sh << 'EOF'
#!/bin/bash

# Build ProofMode XCFramework for iOS
# Run this script on macOS with Xcode installed

set -e

echo "🔨 Building ProofMode XCFramework for iOS"

# Check prerequisites
if [[ "$OSTYPE" != "darwin"* ]]; then
    echo "❌ This script must be run on macOS"
    exit 1
fi

if ! command -v xcodebuild &> /dev/null; then
    echo "❌ Xcode not found. Please install Xcode from the App Store."
    exit 1
fi

# Build using cargo-make
echo "📦 Building iOS libraries..."
cargo make build-ios

echo "🔧 Generating Swift bindings..."
cargo make generate-ios-bindings

echo "📱 Creating XCFramework..."
cargo make create-xcframework

echo "✅ XCFramework created successfully!"
echo "📍 Location: ./target/xcframework/ProofMode.xcframework"
echo ""
echo "Next steps:"
echo "1. Copy the XCFramework to your iOS project"
echo "2. Add it to your Xcode project"
echo "3. Copy the Swift bindings from ./bindings/ios/"
echo "4. Build and run your iOS app!"
EOF

chmod +x scripts/ios/build-framework.sh

# Create iOS project setup script
cat > scripts/ios/setup-xcode-project.sh << 'EOF'
#!/bin/bash

# Setup Xcode project with ProofMode framework
# Run this after building the XCFramework

set -e

echo "📱 Setting up Xcode project with ProofMode"

XCFRAMEWORK_PATH="./target/xcframework/ProofMode.xcframework"
IOS_PROJECT_PATH="./ios-example"
BINDINGS_PATH="./bindings/ios"

# Check if XCFramework exists
if [ ! -d "$XCFRAMEWORK_PATH" ]; then
    echo "❌ XCFramework not found at $XCFRAMEWORK_PATH"
    echo "Please run scripts/ios/build-framework.sh first"
    exit 1
fi

# Copy XCFramework to iOS project
echo "📦 Copying XCFramework to iOS project..."
cp -r "$XCFRAMEWORK_PATH" "$IOS_PROJECT_PATH/"

# Copy Swift bindings
echo "🔧 Copying Swift bindings..."
mkdir -p "$IOS_PROJECT_PATH/ProofModeExample/ProofModeBindings"
cp "$BINDINGS_PATH"/*.swift "$IOS_PROJECT_PATH/ProofModeExample/ProofModeBindings/" 2>/dev/null || echo "No Swift files found"

echo "✅ Xcode project setup complete!"
echo ""
echo "Next steps:"
echo "1. Open ios-example/ProofModeExample.xcodeproj in Xcode"
echo "2. Add ProofMode.xcframework to your project:"
echo "   - Select your project in the navigator"
echo "   - Go to your target's General tab"
echo "   - Drag ProofMode.xcframework to 'Frameworks, Libraries, and Embedded Content'"
echo "3. Add the Swift binding files to your project"
echo "4. Build and run!"
EOF

chmod +x scripts/ios/setup-xcode-project.sh

# Update the iOS README with current instructions
print_status "Updating iOS README..."

cat > ios-example/README.md << 'EOF'
# ProofMode iOS Example App

This is a complete iOS example application demonstrating the usage of ProofMode-Rust library for generating and verifying cryptographic proofs for photos.

## Features

- **Photo Capture**: Take photos directly from the camera or select from photo library
- **Proof Generation**: Generate cryptographic proofs with metadata including:
  - SHA-256 hash of the image
  - Location information (optional)
  - Device information
  - Network information
  - PGP digital signature
- **Proof Verification**: Verify existing proofs and check their validity
- **Proof Management**: View, share, and export proof bundles
- **Privacy Controls**: Control which metadata to include in proofs

## Requirements

- **macOS**: Required for building the XCFramework
- **iOS 16.0+**: Target deployment version
- **Xcode 15.0+**: Development environment
- **Swift 5.9+**: Programming language version

## Quick Setup

### Option 1: Automated Setup (Recommended)

Run the automated setup script from the project root:

```bash
# This will build everything needed for iOS
./scripts/setup-ios.sh
```

If you're on macOS, this will:
1. Install iOS targets
2. Build the Rust library for all iOS architectures
3. Generate Swift bindings
4. Create the XCFramework
5. Set up the Xcode project

### Option 2: Manual Setup

#### Step 1: Build the Framework

From the project root directory:

```bash
# Install iOS build script
chmod +x scripts/ios/build-framework.sh

# Build XCFramework (macOS only)
./scripts/ios/build-framework.sh
```

#### Step 2: Setup Xcode Project

```bash
# Setup Xcode project with framework
./scripts/ios/setup-xcode-project.sh
```

#### Step 3: Open and Configure Xcode Project

1. Open the project:
   ```bash
   cd ios-example
   open ProofModeExample.xcodeproj
   ```

2. Add the framework to your project:
   - Select the ProofModeExample project in the navigator
   - Go to the ProofModeExample target's "General" tab
   - In "Frameworks, Libraries, and Embedded Content":
     - Click the "+" button
     - Click "Add Other..." → "Add Files..."
     - Navigate to and select `ProofMode.xcframework`
     - Choose "Embed & Sign"

3. Add Swift bindings to your project:
   - Right-click on the ProofModeExample group in Xcode
   - Select "Add Files to ProofModeExample"
   - Navigate to `ProofModeExample/ProofModeBindings/`
   - Select all `.swift` files and add them

4. Configure code signing:
   - Select your development team
   - Update the bundle identifier if needed

5. Build and run (⌘+R)

## Project Structure

```
ProofModeExample/
├── ProofModeExampleApp.swift    # Main app entry point
├── Models/
│   └── Proof.swift              # Proof data model
├── Views/
│   ├── ContentView.swift        # Main tab view
│   ├── CameraView.swift         # Camera capture interface
│   ├── ImagePicker.swift        # Photo library picker
│   ├── ProofListView.swift      # List of generated proofs
│   └── ProofDetailView.swift    # Detailed proof information
├── ViewModels/
│   └── ProofViewModel.swift     # Main business logic
├── Services/
│   ├── ProofModeService.swift   # ProofMode library wrapper
│   └── PermissionService.swift  # Permission handling
├── Resources/
│   └── Assets.xcassets          # App assets
└── ProofModeBindings/           # Generated Swift bindings
    └── *.swift                  # UniFFI generated files
```

## Usage

### Generating a Proof

1. Launch the app and go to the "Generate" tab
2. Choose to either:
   - Tap "Take Photo" to capture a new photo
   - Tap "Choose from Library" to select an existing photo
3. The app will automatically:
   - Calculate the SHA-256 hash
   - Collect device and location metadata (if permitted)
   - Generate a PGP signature
   - Save the proof bundle

### Verifying a Proof

1. Go to the "Verify" tab
2. Select a proof from the list
3. View detailed information including:
   - Original image
   - Cryptographic hash
   - Location data (if included)
   - Device information
   - Digital signature
4. Tap "Verify Proof" to validate the signature

## Development Notes

### Integrating with Real ProofMode Library

The example app initially uses mock implementations. To integrate with the actual ProofMode-Rust library:

1. Ensure the XCFramework is properly added to your project
2. In `ProofModeService.swift`, replace mock implementations with actual ProofMode calls
3. Handle errors and progress callbacks as needed
4. Test thoroughly on both simulator and device

### Permissions

The app requires these permissions (requested only when needed):
- **Camera**: `NSCameraUsageDescription`
- **Photo Library**: `NSPhotoLibraryUsageDescription`  
- **Location**: `NSLocationWhenInUseUsageDescription`

### Architecture Notes

- Uses SwiftUI for the user interface
- Follows MVVM architecture pattern
- Implements proper error handling and user feedback
- Supports both simulator and device builds
- Uses async/await for asynchronous operations

## Troubleshooting

### Build Issues

**"No such module 'ProofMode'"**
- Ensure the XCFramework is properly added to your project
- Check that it's set to "Embed & Sign"
- Clean build folder (⌘+Shift+K) and rebuild

**"dyld: Library not loaded"**
- Ensure the framework is embedded, not just linked
- Check that the framework is built for the correct architecture

**"Missing Swift bindings"**
- Ensure Swift binding files are added to your Xcode project
- Check that the files are included in the target membership

### Runtime Issues

**"ProofMode not initialized"**
- Call `proofMode.initialize()` before using other methods
- Check that initialization completes successfully

**"Permission denied"**
- Ensure proper usage descriptions in Info.plist
- Handle permission requests gracefully in your code

## Contributing

This example app demonstrates core ProofMode functionality. Contributions are welcome for:
- Additional verification methods
- Enhanced UI/UX
- Better error handling
- Performance optimizations
- Additional metadata types

## License

This example app is part of the ProofMode-Rust project and follows the same Apache 2.0 license terms.
EOF

print_success "iOS README updated"

# Create development checklist
cat > ios-example/DEVELOPMENT.md << 'EOF'
# iOS Development Checklist

## Pre-Development Setup

- [ ] macOS machine with Xcode installed
- [ ] Rust toolchain installed (`rustup.rs`)
- [ ] cargo-make installed (`cargo install cargo-make`)
- [ ] iOS targets installed (`rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim`)

## Building ProofMode Framework

- [ ] Run setup script: `./scripts/setup-ios.sh`
- [ ] Verify XCFramework created: `ls target/xcframework/ProofMode.xcframework`
- [ ] Verify Swift bindings generated: `ls bindings/ios/*.swift`

## Xcode Project Setup

- [ ] XCFramework added to project and set to "Embed & Sign"
- [ ] Swift binding files added to project
- [ ] Bundle identifier configured
- [ ] Development team selected
- [ ] Signing configured

## Testing Checklist

### Simulator Testing
- [ ] App launches successfully
- [ ] Camera interface works (mock camera in simulator)
- [ ] Photo library access works
- [ ] Proof generation completes
- [ ] Proof verification works
- [ ] Settings and permissions handled gracefully

### Device Testing  
- [ ] App launches on physical device
- [ ] Real camera capture works
- [ ] GPS location collection works (if permissions granted)
- [ ] Proof generation with real metadata
- [ ] Proof files saved to device storage
- [ ] Sharing and export functionality

### Permission Testing
- [ ] Camera permission requested when needed
- [ ] Photo library permission requested when needed
- [ ] Location permission requested when needed
- [ ] App functions when permissions denied
- [ ] Permission status displayed correctly in settings

### Error Handling
- [ ] Network errors handled gracefully
- [ ] Storage errors handled
- [ ] Invalid input handled
- [ ] Library initialization errors handled
- [ ] User feedback provided for all error states

## Performance Testing

- [ ] App launches quickly
- [ ] Image processing performs well
- [ ] Memory usage reasonable
- [ ] Battery usage acceptable
- [ ] Background processing works correctly

## Security Testing

- [ ] PGP keys generated securely
- [ ] Private keys stored securely
- [ ] Image data not leaked
- [ ] Location data only collected when permitted
- [ ] Proof signatures verify correctly

## Release Preparation

- [ ] All features working on both simulator and device
- [ ] Performance acceptable
- [ ] Memory leaks addressed
- [ ] Crash testing completed
- [ ] App Store guidelines compliance
- [ ] Privacy policy updated
- [ ] Documentation complete

## Known Limitations

- [ ] Mock implementation vs real library documented
- [ ] Platform-specific behaviors noted
- [ ] Dependency requirements documented
- [ ] Build environment requirements specified
EOF

# Final instructions
print_status "Creating final setup instructions..."

cat > SETUP_IOS.md << 'EOF'
# iOS Setup Instructions

## For macOS Users (Full Setup)

### 1. Run the Setup Script
```bash
./scripts/setup-ios.sh
```

This will:
- Install iOS targets
- Build the Rust library
- Generate Swift bindings  
- Create XCFramework
- Set up Xcode project

### 2. Open in Xcode
```bash
cd ios-example
open ProofModeExample.xcodeproj
```

### 3. Configure and Run
- Select your development team
- Update bundle identifier if needed
- Build and run (⌘+R)

## For Non-macOS Users (Preparation Only)

### 1. Run Setup Script
```bash
./scripts/setup-ios.sh
```

This will create mock bindings and prepare project structure.

### 2. Review Generated Files
- Check `ios-example/` for complete Xcode project
- Review `bindings/ios/ProofMode.swift` for API structure
- Read `ios-example/README.md` for detailed instructions

### 3. When You Have Access to macOS
- Transfer the entire project directory
- Run `./scripts/setup-ios.sh` again on macOS
- Follow the Xcode setup instructions

## Next Steps

1. **Review the Code**: Examine the example app structure
2. **Understand the API**: Look at the generated Swift bindings
3. **Plan Integration**: Decide how to integrate ProofMode into your app
4. **Test Thoroughly**: Use both simulator and device testing

The iOS example app provides a complete working implementation that you can use as a reference or starting point for your own iOS integration.
EOF

print_success "iOS setup completed!"

echo ""
echo "📋 Summary:"
echo "==========="
echo "✅ iOS targets configured"
echo "✅ Directory structure created"
echo "✅ Build scripts created"
echo "✅ Documentation updated"

if $MACOS; then
    echo "✅ iOS libraries built"
    echo "✅ XCFramework created"
    echo "✅ Swift bindings generated"
    echo ""
    echo "🚀 Ready to use! Open ios-example/ProofModeExample.xcodeproj in Xcode"
else
    echo "⚠️  Mock bindings created (macOS required for actual builds)"
    echo ""
    echo "📝 Next steps for macOS:"
    echo "   1. Transfer this project to a Mac"
    echo "   2. Run this script again on macOS"
    echo "   3. Open the Xcode project and build"
fi

echo ""
echo "📖 Documentation:"
echo "   - iOS README: ios-example/README.md"
echo "   - Setup guide: SETUP_IOS.md"
echo "   - Development checklist: ios-example/DEVELOPMENT.md"
echo ""
echo "🎉 iOS setup complete! Happy coding!"