# SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
#
# SPDX-License-Identifier: CC0-1.0

version: "3"

vars:
  VERSION:
    sh: git describe --tags --always 2>/dev/null || echo "v0.0.0"
  GOOS:
    sh: go env GOOS
  GOARCH:
    sh: go env GOARCH

env:
  CGO_ENABLED: 0

tasks:
  default:
    desc: Run all checks
    cmds:
      - task: fmt
      - task: lint:fix
      - task: staticcheck
      - task: test
      - task: vuln
      - task: reuse

  fmt:
    cmds:
      - go install mvdan.cc/gofumpt@latest
      - gofumpt -l -w .

  lint:
    cmds:
      - golangci-lint run

  lint:fix:
    cmds:
      - golangci-lint run --fix

  staticcheck:
    cmds:
      - go install honnef.co/go/tools/cmd/staticcheck@latest
      - staticcheck ./...

  test:
    cmds:
      - go test -v ./...

  vuln:
    cmds:
      - go install golang.org/x/vuln/cmd/govulncheck@latest
      - govulncheck ./...

  reuse:
    desc: Lint licenses and copyright headers
    cmds:
      - reuse lint

  build:
    cmds:
      - go build -o lune -ldflags "-s -w -X main.version={{.VERSION}}"
    generates:
      - lune

  install:
    cmds:
      - go install -ldflags "-s -w -X main.version={{.VERSION}}"

  run:
    cmds:
      - go run -ldflags "-s -w -X main.version={{.VERSION}}" . {{.CLI_ARGS}}

  pack:
    desc: Pack lune with UPX
    cmds:
      - upx --best -qo lune.min lune
      - mv lune.min lune
    sources:
      - lune

  clean:
    desc: Remove build artifacts
    cmds:
      - rm -rf lune dist/

  clean-all:
    desc: Remove build artifacts and config.toml
    cmds:
      - rm -rf lune config.toml

  release:build:
    desc: Cross-compile for all release targets
    vars:
      TARGETS: >-
        linux/amd64
        linux/arm64
        darwin/amd64
        darwin/arm64
        windows/amd64
        freebsd/amd64
    cmds:
      - rm -rf dist
      - mkdir -p dist
      - for: {var: TARGETS, split: " "}
        cmd: |
          os=$(echo {{.ITEM}} | cut -d/ -f1)
          arch=$(echo {{.ITEM}} | cut -d/ -f2)
          ext=""; if [ "$os" = "windows" ]; then ext=".exe"; fi
          echo "Building ${os}/${arch}..."
          GOOS=${os} GOARCH=${arch} go build \
            -o "dist/lune-{{.VERSION}}-${os}-${arch}${ext}" \
            -ldflags "-s -w -X main.version={{.VERSION}}"

  release:pack:
    desc: Compress release binaries with UPX where supported
    vars:
      # UPX 5.x dropped macOS support; windows/amd64 is PE32 only and
      # freebsd/amd64 is ELF32 only, so only Linux targets are packed.
      PACK_TARGETS: >-
        linux-amd64
        linux-arm64
    cmds:
      - for: {var: PACK_TARGETS, split: " "}
        cmd: |
          bin="dist/lune-{{.VERSION}}-{{.ITEM}}"
          if [ -f "$bin" ]; then
            echo "Packing {{.ITEM}}..."
            upx -q "$bin"
          fi

  release:upload:
    desc: Upload release artifacts
    cmds:
      - fish -c 'release upload lune {{.VERSION}} --latest dist/*'

  release:all:
    desc: Tag, build, pack, and upload a release
    cmds:
      - task release
      - task release:build
      - task release:pack
      - task release:upload

  release:
    desc: Interactive release workflow
    vars:
      BUMP:
        sh: gum choose "major" "minor" "patch" "prerelease"
      CURRENT_VERSION:
        sh: git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"
      IS_CURRENT_PRERELEASE:
        sh: |
          current="{{.CURRENT_VERSION}}"
          if echo "$current" | grep -qE '\-[a-zA-Z]+\.[0-9]+$'; then
            echo "yes"
          else
            echo "no"
          fi
      IS_PRERELEASE:
        sh: |
          if [ "{{.BUMP}}" = "prerelease" ]; then
            echo "yes"
          else
            gum confirm "Create pre-release?" && echo "yes" || echo "no"
          fi
      PRERELEASE_SUFFIX:
        sh: |
          if [ "{{.BUMP}}" = "prerelease" ] && [ "{{.IS_CURRENT_PRERELEASE}}" = "yes" ]; then
            # Extract suffix from current version (e.g., v1.2.3-beta.0 -> beta)
            echo "{{.CURRENT_VERSION}}" | sed -E 's/.*-([a-zA-Z]+)\.[0-9]+$/\1/'
          elif [ "{{.IS_PRERELEASE}}" = "yes" ]; then
            gum input --placeholder "Enter pre-release suffix (e.g., beta, rc)"
          fi
      BASE_NEXT:
        sh: |
          if [ "{{.BUMP}}" = "prerelease" ] && [ "{{.IS_CURRENT_PRERELEASE}}" = "yes" ]; then
            # Extract base version from current prerelease (e.g., v1.2.3-beta.0 -> v1.2.3)
            echo "{{.CURRENT_VERSION}}" | sed -E 's/-[a-zA-Z]+\.[0-9]+$//'
          else
            svu {{.BUMP}}
          fi
      SUFFIX_VERSION:
        sh: |
          if [ "{{.IS_PRERELEASE}}" = "yes" ] && [ -n "{{.PRERELEASE_SUFFIX}}" ]; then
            if [ "{{.BUMP}}" = "prerelease" ] && [ "{{.IS_CURRENT_PRERELEASE}}" = "yes" ]; then
              # Increment the current prerelease number
              current_num=$(echo "{{.CURRENT_VERSION}}" | sed -E 's/.*-[a-zA-Z]+\.([0-9]+)$/\1/')
              echo $((current_num + 1))
            else
              # Find existing tags with this suffix and get the highest version number
              highest=$(git tag -l "{{.BASE_NEXT}}-{{.PRERELEASE_SUFFIX}}.*" | \
                sed 's/.*-{{.PRERELEASE_SUFFIX}}\.//' | \
                sort -n | tail -1)
              if [ -n "$highest" ]; then
                echo $((highest + 1))
              else
                echo 0
              fi
            fi
          fi
      NEXT:
        sh: |
          if [ "{{.IS_PRERELEASE}}" = "yes" ] && [ -n "{{.PRERELEASE_SUFFIX}}" ]; then
            echo "{{.BASE_NEXT}}-{{.PRERELEASE_SUFFIX}}.{{.SUFFIX_VERSION}}"
          else
            echo "{{.BASE_NEXT}}"
          fi
    prompt: "Release {{.NEXT}}?"
    preconditions:
      - sh: '[ $(git symbolic-ref --short HEAD) = "main" ] || [ $(git symbolic-ref --short HEAD) = "dev" ]'
        msg: Not on main or dev branch
      - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
        msg: "Git is dirty"
    cmds:
      - git tag {{.NEXT}}
      - git push soft {{.NEXT}}
      - go list -m git.secluded.site/lune@{{.NEXT}} > /dev/null
      - echo "Released {{.NEXT}} and notified module proxy"
