version: "3"

includes:
  common: ../Taskfile.yml

vars:
  BUNDLE_ID: '{{.BUNDLE_ID | default "com.wails.app"}}'
  # SDK_PATH is computed lazily at task-level to avoid errors on non-macOS systems
  # Each task that needs it defines SDK_PATH in its own vars section

tasks:
  install:deps:
    summary: Check and install iOS development dependencies
    cmds:
      - go run build/ios/scripts/deps/install_deps.go
    env:
      TASK_FORCE_YES: "{{if .YES}}true{{else}}false{{end}}"
    prompt: This will check and install iOS development dependencies. Continue?

  # Note: Bindings generation may show CGO warnings for iOS C imports.
  # These warnings are harmless and don't affect the generated bindings,
  # as the generator only needs to parse Go types, not C implementations.
  build:
    summary: Creates a build of the application for iOS
    deps:
      - task: generate:ios:overlay
      - task: generate:ios:xcode
      - task: common:go:mod:tidy
      - task: generate:ios:bindings
        vars:
          BUILD_FLAGS:
            ref: .BUILD_FLAGS
      - task: common:build:frontend
        vars:
          BUILD_FLAGS:
            ref: .BUILD_FLAGS
          PRODUCTION:
            ref: .PRODUCTION
      - task: common:generate:icons
    cmds:
      - echo "Building iOS app {{.APP_NAME}}..."
      - go build -buildmode=c-archive -overlay build/ios/xcode/overlay.json {{.BUILD_FLAGS}} -o {{.OUTPUT}}.a
    vars:
      BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production,ios -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-tags ios,debug -buildvcs=false -gcflags=all="-l"{{end}}'
      DEFAULT_OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}"
      OUTPUT: "{{ .OUTPUT | default .DEFAULT_OUTPUT }}"
      SDK_PATH:
        sh: xcrun --sdk iphonesimulator --show-sdk-path
    env:
      GOOS: ios
      CGO_ENABLED: 1
      GOARCH: '{{.ARCH | default "arm64"}}'
      PRODUCTION: '{{.PRODUCTION | default "false"}}'
      CGO_CFLAGS: "-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator -mios-simulator-version-min=15.0"
      CGO_LDFLAGS: "-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator"

  compile:objc:
    summary: Compile Objective-C iOS wrapper
    vars:
      SDK_PATH:
        sh: xcrun --sdk iphonesimulator --show-sdk-path
    cmds:
      - xcrun -sdk iphonesimulator clang -target arm64-apple-ios15.0-simulator -isysroot {{.SDK_PATH}} -framework Foundation -framework UIKit -framework WebKit -o {{.BIN_DIR}}/{{.APP_NAME}} build/ios/main.m
      - codesign --force --sign - "{{.BIN_DIR}}/{{.APP_NAME}}"

  package:
    summary: Packages a production build of the application into a `.app` bundle
    deps:
      - task: build
        vars:
          PRODUCTION: "true"
    cmds:
      - task: create:app:bundle

  create:app:bundle:
    summary: Creates an iOS `.app` bundle
    cmds:
      - rm -rf "{{.BIN_DIR}}/{{.APP_NAME}}.app"
      - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.app"
      - cp "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}.app/"
      - cp build/ios/Info.plist "{{.BIN_DIR}}/{{.APP_NAME}}.app/"
      - |
        # Compile asset catalog and embed icons in the app bundle
        APP_BUNDLE="{{.BIN_DIR}}/{{.APP_NAME}}.app"
        AC_IN="build/ios/xcode/main/Assets.xcassets"
        if [ -d "$AC_IN" ]; then
          TMP_AC=$(mktemp -d)
          xcrun actool \
            --compile "$TMP_AC" \
            --app-icon AppIcon \
            --platform iphonesimulator \
            --minimum-deployment-target 15.0 \
            --product-type com.apple.product-type.application \
            --target-device iphone \
            --target-device ipad \
            --output-partial-info-plist "$APP_BUNDLE/assetcatalog_generated_info.plist" \
            "$AC_IN"
          if [ -f "$TMP_AC/Assets.car" ]; then
            cp -f "$TMP_AC/Assets.car" "$APP_BUNDLE/Assets.car"
          fi
          rm -rf "$TMP_AC"
          if [ -f "$APP_BUNDLE/assetcatalog_generated_info.plist" ]; then
            /usr/libexec/PlistBuddy -c "Merge $APP_BUNDLE/assetcatalog_generated_info.plist" "$APP_BUNDLE/Info.plist" || true
          fi
        fi
      - codesign --force --sign - "{{.BIN_DIR}}/{{.APP_NAME}}.app"

  deploy-simulator:
    summary: Deploy to iOS Simulator
    deps: [package]
    cmds:
      - xcrun simctl terminate booted {{.BUNDLE_ID}} 2>/dev/null || true
      - xcrun simctl uninstall booted {{.BUNDLE_ID}} 2>/dev/null || true
      - xcrun simctl install booted "{{.BIN_DIR}}/{{.APP_NAME}}.app"
      - xcrun simctl launch booted {{.BUNDLE_ID}}

  compile:ios:
    summary: Compile the iOS executable from Go archive and main.m
    deps:
      - task: build
    vars:
      SDK_PATH:
        sh: xcrun --sdk iphonesimulator --show-sdk-path
    cmds:
      - |
        MAIN_M=build/ios/xcode/main/main.m
        if [ ! -f "$MAIN_M" ]; then
          MAIN_M=build/ios/main.m
        fi
        xcrun -sdk iphonesimulator clang \
          -target arm64-apple-ios15.0-simulator \
          -isysroot {{.SDK_PATH}} \
          -framework Foundation -framework UIKit -framework WebKit \
          -framework Security -framework CoreFoundation \
          -lresolv \
          -o "{{.BIN_DIR}}/{{.APP_NAME | lower}}" \
          "$MAIN_M" "{{.BIN_DIR}}/{{.APP_NAME}}.a"

  generate:ios:bindings:
    internal: true
    summary: Generates bindings for iOS with proper CGO flags
    sources:
      - "**/*.go"
      - go.mod
      - go.sum
    generates:
      - frontend/bindings/**/*
    vars:
      SDK_PATH:
        sh: xcrun --sdk iphonesimulator --show-sdk-path
    cmds:
      - wails3 generate bindings -f '{{.BUILD_FLAGS}}' -clean=true
    env:
      GOOS: ios
      CGO_ENABLED: 1
      GOARCH: '{{.ARCH | default "arm64"}}'
      CGO_CFLAGS: "-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator -mios-simulator-version-min=15.0"
      CGO_LDFLAGS: "-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator"

  ensure-simulator:
    internal: true
    summary: Ensure iOS Simulator is running and booted
    silent: true
    cmds:
      - |
        if ! xcrun simctl list devices booted | grep -q "Booted"; then
          echo "Starting iOS Simulator..."
          # Get first available iPhone device
          DEVICE_ID=$(xcrun simctl list devices available | grep "iPhone" | head -1 | grep -o "[A-F0-9-]\{36\}" || true)
          if [ -z "$DEVICE_ID" ]; then
            echo "No iPhone simulator found. Creating one..."
            RUNTIME=$(xcrun simctl list runtimes | grep iOS | tail -1 | awk '{print $NF}')
            DEVICE_ID=$(xcrun simctl create "iPhone 15 Pro" "iPhone 15 Pro" "$RUNTIME")
          fi
          # Boot the device
          echo "Booting device $DEVICE_ID..."
          xcrun simctl boot "$DEVICE_ID" 2>/dev/null || true
          # Open Simulator app
          open -a Simulator
          # Wait for boot (max 30 seconds)
          for i in {1..30}; do
            if xcrun simctl list devices booted | grep -q "Booted"; then
              echo "Simulator booted successfully"
              break
            fi
            sleep 1
          done
          # Final check
          if ! xcrun simctl list devices booted | grep -q "Booted"; then
            echo "Failed to boot simulator after 30 seconds"
            exit 1
          fi
        fi
    preconditions:
      - sh: command -v xcrun
        msg: "xcrun not found. Please run 'wails3 task ios:install:deps' to install iOS development dependencies"

  generate:ios:overlay:
    internal: true
    summary: Generate Go build overlay and iOS shim
    sources:
      - build/config.yml
    generates:
      - build/ios/xcode/overlay.json
      - build/ios/xcode/gen/main_ios.gen.go
    cmds:
      - wails3 ios overlay:gen -out build/ios/xcode/overlay.json -config build/config.yml

  generate:ios:xcode:
    internal: true
    summary: Generate iOS Xcode project structure and assets
    sources:
      - build/config.yml
      - build/appicon.png
    generates:
      - build/ios/xcode/main/main.m
      - build/ios/xcode/main/Assets.xcassets/**/*
      - build/ios/xcode/project.pbxproj
    cmds:
      - wails3 ios xcode:gen -outdir build/ios/xcode -config build/config.yml

  run:
    summary: Run the application in iOS Simulator
    deps:
      - task: ensure-simulator
      - task: compile:ios
    cmds:
      - rm -rf "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app"
      - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app"
      - cp "{{.BIN_DIR}}/{{.APP_NAME | lower}}" "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/{{.APP_NAME | lower}}"
      - cp build/ios/Info.dev.plist "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Info.plist"
      - |
        # Compile asset catalog and embed icons for dev bundle
        APP_BUNDLE="{{.BIN_DIR}}/{{.APP_NAME}}.dev.app"
        AC_IN="build/ios/xcode/main/Assets.xcassets"
        if [ -d "$AC_IN" ]; then
          TMP_AC=$(mktemp -d)
          xcrun actool \
            --compile "$TMP_AC" \
            --app-icon AppIcon \
            --platform iphonesimulator \
            --minimum-deployment-target 15.0 \
            --product-type com.apple.product-type.application \
            --target-device iphone \
            --target-device ipad \
            --output-partial-info-plist "$APP_BUNDLE/assetcatalog_generated_info.plist" \
            "$AC_IN"
          if [ -f "$TMP_AC/Assets.car" ]; then
            cp -f "$TMP_AC/Assets.car" "$APP_BUNDLE/Assets.car"
          fi
          rm -rf "$TMP_AC"
          if [ -f "$APP_BUNDLE/assetcatalog_generated_info.plist" ]; then
            /usr/libexec/PlistBuddy -c "Merge $APP_BUNDLE/assetcatalog_generated_info.plist" "$APP_BUNDLE/Info.plist" || true
          fi
        fi
      - codesign --force --sign - "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app"
      - xcrun simctl terminate booted "com.wails.{{.APP_NAME | lower}}.dev" 2>/dev/null || true
      - xcrun simctl uninstall booted "com.wails.{{.APP_NAME | lower}}.dev" 2>/dev/null || true
      - xcrun simctl install booted "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app"
      - xcrun simctl launch booted "com.wails.{{.APP_NAME | lower}}.dev"

  xcode:
    summary: Open the generated Xcode project for this app
    cmds:
      - task: generate:ios:xcode
      - open build/ios/xcode/main.xcodeproj

  logs:
    summary: Stream iOS Simulator logs filtered to this app
    cmds:
      - |
        xcrun simctl spawn booted log stream \
          --level debug \
          --style compact \
          --predicate 'senderImagePath CONTAINS[c] "{{.APP_NAME | lower}}.app/" OR composedMessage CONTAINS[c] "{{.APP_NAME | lower}}" OR eventMessage CONTAINS[c] "{{.APP_NAME | lower}}" OR process == "{{.APP_NAME | lower}}" OR category CONTAINS[c] "{{.APP_NAME | lower}}"'

  logs:dev:
    summary: Stream logs for the dev bundle (used by `task ios:run`)
    cmds:
      - |
        xcrun simctl spawn booted log stream \
          --level debug \
          --style compact \
          --predicate 'senderImagePath CONTAINS[c] ".dev.app/" OR subsystem == "com.wails.{{.APP_NAME | lower}}.dev" OR process == "{{.APP_NAME | lower}}"'

  logs:wide:
    summary: Wide log stream to help discover the exact process/bundle identifiers
    cmds:
      - |
        xcrun simctl spawn booted log stream \
          --level debug \
          --style compact \
          --predicate 'senderImagePath CONTAINS[c] ".app/"'
