version: '3'

includes:
  common: ../Taskfile.yml

vars:
  # Docker image for cross-compilation (used when building on non-macOS)
  CROSS_IMAGE: wails-cross

tasks:
  build:
    summary: Builds the application
    cmds:
      - task: '{{if eq OS "darwin"}}build:native{{else}}build:docker{{end}}'
        vars:
          ARCH: '{{.ARCH}}'
          DEV: '{{.DEV}}'
          OUTPUT: '{{.OUTPUT}}'
          EXTRA_TAGS: '{{.EXTRA_TAGS}}'
          OBFUSCATED: '{{.OBFUSCATED}}'
          GARBLE_ARGS: '{{.GARBLE_ARGS}}'
    vars:
      DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
      OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'

  build:native:
    summary: Builds the application natively on macOS
    internal: true
    deps:
      - task: common:go:mod:tidy
      - task: common:build:frontend
        vars:
          BUILD_FLAGS:
            ref: .BUILD_FLAGS
          OBFUSCATED:
            ref: .OBFUSCATED
          DEV:
            ref: .DEV
      - task: common:generate:icons
    preconditions:
      - sh: '{{if eq .OBFUSCATED "true"}}command -v garble >/dev/null 2>&1{{else}}true{{end}}'
        msg: "garble is required for obfuscated builds. Install it with: go install mvdan.cc/garble@v0.16.0 (requires Go 1.24+). See https://github.com/burrowers/garble/releases for version/toolchain compatibility."
    cmds:
      - '{{if eq .OBFUSCATED "true"}}garble {{.GARBLE_ARGS}} build{{else}}go build{{end}} {{.BUILD_FLAGS}} -o "{{.OUTPUT}}"'
    vars:
      BUILD_FLAGS: '{{if eq .DEV "true"}}{{if or .EXTRA_TAGS (eq .OBFUSCATED "true")}}-tags {{if eq .OBFUSCATED "true"}}wails_obfuscated{{if .EXTRA_TAGS}},{{end}}{{end}}{{.EXTRA_TAGS}} {{end}}-buildvcs=false -gcflags=all="-l"{{else}}-tags production{{if eq .OBFUSCATED "true"}},wails_obfuscated{{end}}{{if .EXTRA_TAGS}},{{.EXTRA_TAGS}}{{end}} -trimpath -buildvcs=false -ldflags="-w -s"{{end}}'
      DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
      OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
    env:
      GOOS: darwin
      CGO_ENABLED: 1
      GOARCH: '{{.ARCH | default ARCH}}'
      CGO_CFLAGS: "-mmacosx-version-min=12.0"
      CGO_LDFLAGS: "-mmacosx-version-min=12.0"
      MACOSX_DEPLOYMENT_TARGET: "12.0"

  build:docker:
    summary: Cross-compiles for macOS using Docker (for Linux/Windows hosts)
    internal: true
    deps:
      - task: common:build:frontend
        vars:
          OBFUSCATED:
            ref: .OBFUSCATED
      - task: common:generate:icons
    preconditions:
      - sh: docker info > /dev/null 2>&1
        msg: "Docker is required for cross-compilation. Please install Docker."
      - sh: docker image inspect {{.CROSS_IMAGE}} > /dev/null 2>&1
        msg: |
          Docker image '{{.CROSS_IMAGE}}' not found.
          Build it first: wails3 task setup:docker
    cmds:
      - docker run --rm -v "{{.ROOT_DIR}}:/app" {{.DOCKER_MOUNTS}} -e APP_NAME="{{.APP_NAME}}" {{if .EXTRA_TAGS}}-e EXTRA_TAGS="{{.EXTRA_TAGS}}"{{end}} {{if eq .OBFUSCATED "true"}}-e OBFUSCATED=true{{end}} {{if .GARBLE_ARGS}}-e GARBLE_ARGS="{{.GARBLE_ARGS}}"{{end}} {{.CROSS_IMAGE}} darwin {{.DOCKER_ARCH}}
      - cmd: docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin
        platforms: [linux, darwin]
      - mkdir -p {{.BIN_DIR}}
      - mv "bin/{{.APP_NAME}}-darwin-{{.DOCKER_ARCH}}" "{{.OUTPUT}}"
    vars:
      DOCKER_ARCH: '{{if eq .ARCH "arm64"}}arm64{{else if eq .ARCH "amd64"}}amd64{{else}}arm64{{end}}'
      DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
      OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
      # Generate Docker volume mounts: Go module cache + go.mod replace directives
      # Uses wails3 tool docker-mounts for cross-platform compatibility (Windows/Linux/macOS)
      DOCKER_MOUNTS:
        sh: 'wails3 tool docker-mounts'

  build:universal:
    summary: Builds darwin universal binary (arm64 + amd64)
    deps:
      - task: build
        vars:
          ARCH: amd64
          OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-amd64"
      - task: build
        vars:
          ARCH: arm64
          OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"
    cmds:
      - task: '{{if eq OS "darwin"}}build:universal:lipo:native{{else}}build:universal:lipo:go{{end}}'

  build:universal:lipo:native:
    summary: Creates universal binary using native lipo (macOS)
    internal: true
    cmds:
      - lipo -create -output "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"
      - rm "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"

  build:universal:lipo:go:
    summary: Creates universal binary using wails3 tool lipo (Linux/Windows)
    internal: true
    cmds:
      - wails3 tool lipo -output "{{.BIN_DIR}}/{{.APP_NAME}}" -input "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" -input "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"
      - rm -f "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"

  package:
    summary: Packages the application into a `.app` bundle
    deps:
      - task: build
    cmds:
      - task: create:app:bundle

  package:universal:
    summary: Packages darwin universal binary (arm64 + amd64)
    deps:
      - task: build:universal
    cmds:
      - task: create:app:bundle


  create:app:bundle:
    summary: Creates an `.app` bundle
    cmds:
      - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS"
      - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources"
      - cp build/darwin/icons.icns "{{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources"
      - |
        if [ -f build/darwin/Assets.car ]; then
          cp build/darwin/Assets.car "{{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources"
        fi
      - cp "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS"
      - cp build/darwin/Info.plist "{{.BIN_DIR}}/{{.APP_NAME}}.app/Contents"
      - task: '{{if eq OS "darwin"}}codesign:adhoc{{else}}codesign:skip{{end}}'

  codesign:adhoc:
    summary: Ad-hoc signs the app bundle (macOS only)
    internal: true
    cmds:
      - codesign --force --deep --sign - "{{.BIN_DIR}}/{{.APP_NAME}}.app"

  codesign:skip:
    summary: Skips codesigning when cross-compiling
    internal: true
    cmds:
      - 'echo "Skipping codesign (not available on {{OS}}). Sign the .app on macOS before distribution."'

  run:
    cmds:
      - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/MacOS"
      - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Resources"
      - cp build/darwin/icons.icns "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Resources"
      - |
        if [ -f build/darwin/Assets.car ]; then
          cp build/darwin/Assets.car "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Resources"
        fi
      - cp "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/MacOS"
      - cp "build/darwin/Info.dev.plist" "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Info.plist"
      - codesign --force --deep --sign - "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app"
      - '"{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/MacOS/{{.APP_NAME}}"'

  sign:
    summary: Signs the application bundle with Developer ID
    desc: |
      Signs the .app bundle for distribution.
      Uses signing identity from `wails3 setup` (stored in ~/.config/wails/defaults.yaml).
      Override with: task darwin:sign -- --identity "Developer ID Application: ..."
    deps:
      - task: package
    cmds:
      - wails3 tool sign --input "{{.BIN_DIR}}/{{.APP_NAME}}.app" {{.CLI_ARGS}}

  sign:notarize:
    summary: Signs and notarizes the application bundle
    desc: |
      Signs the .app bundle and submits it for notarization.
      Uses signing identity and keychain profile from `wails3 setup`.

      First-time setup:
        wails3 setup
    deps:
      - task: package
    cmds:
      - wails3 tool sign --input "{{.BIN_DIR}}/{{.APP_NAME}}.app" --notarize {{.CLI_ARGS}}
