name: CI

on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]

env:
  GO_VERSION: "1.24"

jobs:
  # Core testing across multiple Go versions and platforms
  test:
    name: Test (Go ${{ matrix.go-version }}, ${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        go-version: ["1.24.x"]
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Go ${{ matrix.go-version }}
      uses: actions/setup-go@v5
      with:
        go-version: ${{ matrix.go-version }}
    
    - name: Cache Go modules
      uses: actions/cache@v3
      with:
        path: |
          ~/.cache/go-build
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ matrix.go-version }}-
    
    - name: Download dependencies
      run: go mod download
    
    - name: Verify dependencies
      run: go mod verify
    
    - name: Build
      run: go build -v ./...
    
    - name: Run go vet
      run: go vet ./...
    
    - name: Run tests
      run: go test -v ./...
    
    - name: Run tests with race detector
      run: go test -race -v ./...

  # Code quality and linting
  lint:
    name: Code Quality
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Go
      uses: actions/setup-go@v5
      with:
        go-version: ${{ env.GO_VERSION }}
    
    - name: Cache Go modules
      uses: actions/cache@v3
      with:
        path: |
          ~/.cache/go-build
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ env.GO_VERSION }}-
    
    - name: Download dependencies
      run: go mod download
    
    - name: Run golangci-lint
      uses: golangci/golangci-lint-action@v4
      with:
        version: latest
        args: --timeout=5m
    
    - name: Check formatting
      run: |
        if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
          echo "The following files are not formatted properly:"
          gofmt -s -l .
          exit 1
        fi
    
    - name: Install staticcheck
      run: go install honnef.co/go/tools/cmd/staticcheck@latest
    
    - name: Run staticcheck
      run: staticcheck ./...

  # Security scanning
  security:
    name: Security Scan
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Go
      uses: actions/setup-go@v5
      with:
        go-version: ${{ env.GO_VERSION }}
    
    - name: Download dependencies
      run: go mod download
    
    - name: Run govulncheck
      run: |
        go install golang.org/x/vuln/cmd/govulncheck@latest
        govulncheck ./...

    - name: Run gosec security scanner
      run: |
        go install github.com/securego/gosec/v2/cmd/gosec@latest
        gosec ./...

  # Test coverage
  coverage:
    name: Test Coverage
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Go
      uses: actions/setup-go@v5
      with:
        go-version: ${{ env.GO_VERSION }}
    
    - name: Cache Go modules
      uses: actions/cache@v3
      with:
        path: |
          ~/.cache/go-build
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ env.GO_VERSION }}-
    
    - name: Download dependencies
      run: go mod download
    
    - name: Run tests with coverage
      run: go test -race -coverprofile=coverage.txt -covermode=atomic ./...
    
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v4
      with:
        file: ./coverage.txt
        flags: unittests
        name: codecov-umbrella
        fail_ci_if_error: false

  # Benchmarks
  benchmark:
    name: Benchmarks
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Go
      uses: actions/setup-go@v5
      with:
        go-version: ${{ env.GO_VERSION }}
    
    - name: Cache Go modules
      uses: actions/cache@v3
      with:
        path: |
          ~/.cache/go-build
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ env.GO_VERSION }}-
    
    - name: Download dependencies
      run: go mod download
    
    - name: Run benchmarks
      run: go test -bench=. -benchmem -count=3 ./... > benchmark_results.txt
    
    - name: Upload benchmark results
      uses: actions/upload-artifact@v4
      with:
        name: benchmark-results
        path: benchmark_results.txt
        retention-days: 30

  # Build verification for CLI tool
  build:
    name: Build CLI
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Go
      uses: actions/setup-go@v5
      with:
        go-version: ${{ env.GO_VERSION }}
    
    - name: Cache Go modules
      uses: actions/cache@v3
      with:
        path: |
          ~/.cache/go-build
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ env.GO_VERSION }}-
    
    - name: Download dependencies
      run: go mod download
    
    - name: Build CLI tool
      run: go build -v -o jdenticon-cli ./cmd/jdenticon
    
    - name: Test CLI tool
      run: |
        ./jdenticon-cli generate --help
        ./jdenticon-cli generate "test@example.com" -s 64 -o test.svg
        test -f test.svg
    
    - name: Upload CLI artifact
      uses: actions/upload-artifact@v4
      with:
        name: jdenticon-cli-linux
        path: jdenticon-cli
        retention-days: 7