version: "3"

env:
  HBOX_LOG_LEVEL: debug
  HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_pragma=busy_timeout=1000&_pragma=journal_mode=WAL&_fk=1
  HBOX_OPTIONS_ALLOW_REGISTRATION: true
  UNSAFE_DISABLE_PASSWORD_PROJECTION: "yes_i_am_sure"
tasks:
  setup:
    desc: Install development dependencies
    cmds:
      - go install github.com/swaggo/swag/cmd/swag@latest
      - cd backend && go mod tidy
      - cd frontend && pnpm install --shamefully-hoist

  swag:
    desc: Generate swagger docs
    dir: backend/app/api/static/
    vars:
      API: "../"
      INTERNAL: "../../../internal"
      PKGS: "../../../pkgs"
    cmds:
      - swag fmt --dir={{ .API }}
      - swag init --dir={{ .API }},{{ .INTERNAL }}/core/services,{{ .INTERNAL }}/data/repo --parseDependency
    sources:
      - "./backend/app/api/**/*"
      - "./backend/internal/data/**"
      - "./backend/internal/core/services/**/*"
      - "./backend/app/tools/typegen/main.go"

  typescript-types:
    desc: Generates typescript types from swagger definition
    cmds:
      - |
        npx swagger-typescript-api \
          --no-client \
          --modular \
          --path ./backend/app/api/static/docs/swagger.json \
          --output ./frontend/lib/api/types
      - go run ./backend/app/tools/typegen/main.go ./frontend/lib/api/types/data-contracts.ts
    sources:
      - ./backend/app/tools/typegen/main.go
      - ./backend/app/api/static/docs/swagger.json

  generate:
    deps:
      - db:generate
    cmds:
      - task: swag
      - task: typescript-types
      - cp ./backend/app/api/static/docs/swagger.json docs/docs/api/openapi-2.0.json

  go:run:
    desc: Starts the backend api server (depends on generate task)
    dir: backend
    deps:
      - generate
    cmds:
      - go run ./app/api/ {{ .CLI_ARGS }}
    silent: false

  go:test:
    desc: Runs all go tests using gotestsum - supports passing gotestsum args
    dir: backend
    cmds:
      - gotestsum {{ .CLI_ARGS }} ./...

  go:coverage:
    desc: Runs all go tests with -race flag and generates a coverage report
    dir: backend
    cmds:
      - go test -race -coverprofile=coverage.out -covermode=atomic ./app/... ./internal/... ./pkgs/... -v -cover
    silent: true

  go:tidy:
    desc: Runs go mod tidy on the backend
    dir: backend
    cmds:
      - go mod tidy

  go:lint:
    desc: Runs golangci-lint
    dir: backend
    cmds:
      - golangci-lint run ./...

  go:all:
    desc: Runs all go test and lint related tasks
    cmds:
      - task: go:tidy
      - task: go:lint
      - task: go:test

  go:build:
    desc: Builds the backend binary
    dir: backend
    cmds:
      - go build -o ../build/backend ./app/api

  db:generate:
    desc: Run Entgo.io Code Generation
    dir: backend/internal/
    cmds:
      - |
        go generate ./...
    sources:
      - "./backend/internal/data/ent/schema/**/*"

  db:migration:
    desc: Runs the database diff engine to generate a SQL migration files
    deps:
      - db:generate
    cmds:
      - cd backend && go run app/tools/migrations/main.go {{ .CLI_ARGS }}

  ui:watch:
    desc: Starts the vitest test runner in watch mode
    dir: frontend
    cmds:
      - pnpm run test:watch

  ui:dev:
    desc: Run frontend development server
    dir: frontend
    cmds:
      - pnpm dev

  ui:fix:
    desc: Runs prettier and eslint on the frontend
    dir: frontend
    cmds:
      - pnpm run lint:fix

  ui:check:
    desc: Runs type checking
    dir: frontend
    cmds:
      - pnpm run typecheck

  test:ci:
    desc: Runs end-to-end test on a live server (only for use in CI)
    cmds:
      - cd backend && go build ./app/api
      - backend/api &
      - sleep 5
      - cd frontend && pnpm run test:ci
    silent: true

  pr:
    desc: Runs all tasks required for a PR
    cmds:
      - task: generate
      - task: go:all
      - task: ui:check
      - task: ui:fix
      - task: test:ci