version: '3'

silent: true

vars:
  APP: agent-desk
  MAIN: ./cmd/server
  WEB_DIR: web
  DIST_DIR: dist
  GO:
    sh: 'printf "%s" "${GO:-go}"'
  PNPM:
    sh: 'printf "%s" "${PNPM:-pnpm}"'
  DEV_PORT:
    sh: 'printf "%s" "${DEV_PORT:-8083}"'
  DEV_API_BASE_URL:
    sh: 'printf "%s" "${DEV_API_BASE_URL:-http://127.0.0.1:${DEV_PORT:-8083}}"'
  LANCEDB_VERSION:
    sh: 'printf "%s" "${LANCEDB_VERSION:-v0.1.2}"'
  LANCEDB_DOWNLOAD_SCRIPT:
    sh: 'printf "%s" "${LANCEDB_DOWNLOAD_SCRIPT:-https://raw.githubusercontent.com/lancedb/lancedb-go/main/scripts/download-artifacts.sh}"'
  HOST_OS:
    sh: uname -s
  HOST_ARCH:
    sh: uname -m
  HOST_GOOS:
    sh: '${GO:-go} env GOOS'
  HOST_LANCEDB_PLATFORM:
    sh: |
      case "$(uname -s)" in
        Darwin) printf darwin ;;
        Linux) printf linux ;;
        MINGW*|MSYS*|CYGWIN*) printf windows ;;
        *) printf unsupported ;;
      esac
  HOST_LANCEDB_ARCH:
    sh: |
      case "$(uname -m)" in
        x86_64|amd64) printf amd64 ;;
        arm64|aarch64) printf arm64 ;;
        *) printf unsupported ;;
      esac
  HOST_LANCEDB_TARGET:
    sh: |
      case "$(uname -s)" in
        Darwin) platform=darwin ;;
        Linux) platform=linux ;;
        MINGW*|MSYS*|CYGWIN*) platform=windows ;;
        *) platform=unsupported ;;
      esac
      case "$(uname -m)" in
        x86_64|amd64) arch=amd64 ;;
        arm64|aarch64) arch=arm64 ;;
        *) arch=unsupported ;;
      esac
      printf "%s_%s" "$platform" "$arch"
  HOST_LANCEDB_LIB:
    sh: |
      case "$(uname -s)" in
        Darwin) platform=darwin ;;
        Linux) platform=linux ;;
        MINGW*|MSYS*|CYGWIN*) platform=windows ;;
        *) platform=unsupported ;;
      esac
      case "$(uname -m)" in
        x86_64|amd64) arch=amd64 ;;
        arm64|aarch64) arch=arm64 ;;
        *) arch=unsupported ;;
      esac
      printf "%s/lib/%s_%s/liblancedb_go.a" "{{.ROOT_DIR}}" "$platform" "$arch"
  LANCEDB_CGO_CFLAGS: '-I{{.ROOT_DIR}}/include'

tasks:
  default:
    desc: Show available tasks
    cmds:
      - task --list

  dev:
    desc: Start backend and frontend development servers
    deps:
      - task: dev:backend
      - task: dev:frontend

  build:
    desc: Build the frontend SPA and current-platform Go binary into dist/
    deps:
      - task: build:web
      - task: build:dist
    cmds:
      - |
        ext=""
        if [ "{{.HOST_GOOS}}" = "windows" ]; then
          ext=".exe"
        fi
        output="{{.DIST_DIR}}/{{.APP}}${ext}"
        echo "Building $output..."
        {{.GO}} build -v -o "$output" {{.MAIN}}

  build:lancedb:
    desc: Build the current-platform LanceDB binary into dist/
    deps:
      - task: lancedb:ensure-current
      - task: build:web
      - task: build:dist
    cmds:
      - |
        case "$(uname -s)" in
          Darwin) system_ldflags="-framework Security -framework CoreFoundation" ;;
          Linux) system_ldflags="-lm -ldl -lpthread" ;;
          *) system_ldflags="" ;;
        esac
        ext=""
        if [ "{{.HOST_GOOS}}" = "windows" ]; then
          ext=".exe"
        fi
        output="{{.DIST_DIR}}/{{.APP}}-lancedb${ext}"
        echo "Building $output..."
        CGO_ENABLED=1 CGO_CFLAGS="{{.LANCEDB_CGO_CFLAGS}}" CGO_LDFLAGS="{{.HOST_LANCEDB_LIB}} $system_ldflags" \
          {{.GO}} build -tags lancedb -v -o "$output" {{.MAIN}}

  release:
    desc: Build linux/darwin/windows release binaries into dist/
    deps:
      - task: build:web
      - task: build:dist
    cmds:
      - |
        echo "Building release binaries in {{.DIST_DIR}}..."
        GOOS=linux GOARCH=amd64 {{.GO}} build -v -o "{{.DIST_DIR}}/{{.APP}}-linux-amd64" {{.MAIN}}
        GOOS=linux GOARCH=arm64 {{.GO}} build -v -o "{{.DIST_DIR}}/{{.APP}}-linux-arm64" {{.MAIN}}
        GOOS=darwin GOARCH=amd64 {{.GO}} build -v -o "{{.DIST_DIR}}/{{.APP}}-darwin-amd64" {{.MAIN}}
        GOOS=darwin GOARCH=arm64 {{.GO}} build -v -o "{{.DIST_DIR}}/{{.APP}}-darwin-arm64" {{.MAIN}}
        GOOS=windows GOARCH=amd64 {{.GO}} build -v -o "{{.DIST_DIR}}/{{.APP}}-windows-amd64.exe" {{.MAIN}}

  release:lancedb:
    desc: Build LanceDB release binaries into dist/
    deps:
      - task: lancedb:check-release
      - task: build:web
      - task: build:dist
    cmds:
      - |
        echo "Building LanceDB release binaries in {{.DIST_DIR}}..."
        build_lancedb() {
          platform="$1"
          arch="$2"
          ext="$3"
          system_ldflags="$4"
          native_lib="{{.ROOT_DIR}}/lib/${platform}_${arch}/liblancedb_go.a"
          output="{{.DIST_DIR}}/{{.APP}}-lancedb-${platform}-${arch}${ext}"
          echo "Building $output..."
          CGO_ENABLED=1 CGO_CFLAGS="-I{{.ROOT_DIR}}/include" CGO_LDFLAGS="$native_lib $system_ldflags" \
            GOOS="$platform" GOARCH="$arch" {{.GO}} build -tags lancedb -v -o "$output" {{.MAIN}}
        }
        build_lancedb linux amd64 "" "-lm -ldl -lpthread"
        build_lancedb linux arm64 "" "-lm -ldl -lpthread"
        build_lancedb darwin amd64 "" "-framework Security -framework CoreFoundation"
        build_lancedb darwin arm64 "" "-framework Security -framework CoreFoundation"
        build_lancedb windows amd64 ".exe" ""

  generator:
    desc: Run code generation
    cmds:
      - '{{.GO}} run ./cmd/generator/generator.go'

  enums:
    desc: Generate frontend enums
    cmds:
      - '{{.GO}} run ./cmd/enums/generator.go'

  dev:backend:
    internal: true
    cmds:
      - task: lancedb:ensure-current
      - |
        echo "Starting backend on http://127.0.0.1:{{.DEV_PORT}} ..."
        case "$(uname -s)" in
          Darwin) system_ldflags="-framework Security -framework CoreFoundation" ;;
          Linux) system_ldflags="-lm -ldl -lpthread" ;;
          *) system_ldflags="" ;;
        esac
        AGENT_DESK_SERVER_PORT="{{.DEV_PORT}}" CGO_ENABLED=1 CGO_CFLAGS="{{.LANCEDB_CGO_CFLAGS}}" CGO_LDFLAGS="{{.HOST_LANCEDB_LIB}} $system_ldflags" \
          {{.GO}} run -tags "dev lancedb" {{.MAIN}}

  dev:frontend:
    internal: true
    deps:
      - task: build:flowgram-editor
    cmds:
      - |
        echo "Starting frontend on http://localhost:3000 ..."
        cd {{.WEB_DIR}} && NEXT_PUBLIC_API_BASE_URL="" NEXT_API_BASE_URL="{{.DEV_API_BASE_URL}}" {{.PNPM}} dev

  build:web:
    internal: true
    deps:
      - task: build:flowgram-editor
    cmds:
      - 'cd {{.WEB_DIR}} && {{.PNPM}} build:sdk && {{.PNPM}} build'

  build:flowgram-editor:
    internal: true
    sources:
      - flowgram-editor/src/**/*
      - flowgram-editor/package.json
      - flowgram-editor/pnpm-lock.yaml
      - flowgram-editor/rsbuild.config.ts
    generates:
      - web/public/flowgram-editor/index.html
    cmds:
      - 'cd flowgram-editor && {{.PNPM}} install --frozen-lockfile'
      - 'cd flowgram-editor && {{.PNPM}} build'

  build:dist:
    internal: true
    cmds:
      - 'mkdir -p {{.DIST_DIR}}'

  lancedb:ensure-current:
    internal: true
    cmds:
      - |
        if [ "{{.HOST_LANCEDB_PLATFORM}}" = "unsupported" ] || [ "{{.HOST_LANCEDB_ARCH}}" = "unsupported" ]; then
          echo "Unsupported LanceDB platform: {{.HOST_OS}}/{{.HOST_ARCH}}"
          exit 1
        fi
      - |
        if [ -f "{{.HOST_LANCEDB_LIB}}" ] && [ -f "{{.ROOT_DIR}}/include/lancedb.h" ]; then
          echo "LanceDB native artifacts already exist for {{.HOST_LANCEDB_TARGET}}."
        else
          echo "Downloading LanceDB native artifacts {{.LANCEDB_VERSION}} for {{.HOST_LANCEDB_TARGET}}..."
          curl -sSL "{{.LANCEDB_DOWNLOAD_SCRIPT}}" | bash -s "{{.LANCEDB_VERSION}}"
        fi
      - |
        if [ ! -f "{{.HOST_LANCEDB_LIB}}" ]; then
          echo "Missing LanceDB native library: {{.HOST_LANCEDB_LIB}}"
          exit 1
        fi
      - |
        if [ ! -f "{{.ROOT_DIR}}/include/lancedb.h" ]; then
          echo "Missing LanceDB header: {{.ROOT_DIR}}/include/lancedb.h"
          exit 1
        fi

  lancedb:check-release:
    internal: true
    cmds:
      - |
        if [ ! -f "{{.ROOT_DIR}}/include/lancedb.h" ]; then
          echo "Missing LanceDB header: {{.ROOT_DIR}}/include/lancedb.h"
          exit 1
        fi
      - |
        missing=0
        for target in linux_amd64 linux_arm64 darwin_amd64 darwin_arm64 windows_amd64; do
          native_lib="{{.ROOT_DIR}}/lib/${target}/liblancedb_go.a"
          if [ ! -f "$native_lib" ]; then
            echo "Missing LanceDB native library: $native_lib"
            missing=1
          fi
        done
        if [ "$missing" = "1" ]; then
          echo "LanceDB release builds require matching native artifacts and a CGO-capable toolchain for each target platform."
          exit 1
        fi
