name: CI/CD Pipeline

"on":
  push:
    branches: [ master, develop ]
    tags: [ 'v*.*.*' ]
  pull_request:
    branches: [ master ]

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  fmt:
    name: Code Format
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          rustup component add rustfmt
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Check formatting
        run: cargo fmt --all -- --check

  clippy:
    name: Clippy Lints
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          rustup component add clippy
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get -f install -y
          sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
      - name: Run clippy
        run: cargo clippy --all-targets --all-features -- -D warnings

  test:
    name: All Unit Tests
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get -f install -y
          sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
      - name: Run tests
        run: cargo test --all-features

  audit:
    name: Security Audit
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get -f install -y
          sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
      - name: Run cargo-audit
        run: |
          cargo install cargo-audit
          cargo audit --ignore RUSTSEC-2025-0134

  enrollment-tests:
    name: Enrollment Tests
    needs: [fmt, clippy]
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get -f install -y
          sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
      - name: Run enrollment unit tests
        run: cargo test --test enroll_identity
      - name: Run enrollment integration tests
        run: cargo test --test enrollment_test
      - name: Run enrollment E2E tests
        run: cargo test --test enrollment_e2e

  verify-enrollment-cli:
    name: Verify Enrollment CLI Flag
    needs: [clippy]
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get -f install -y
          sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
      - name: Build binary
        run: cargo build
      - name: Verify --enroll flag exists
        run: cargo run -- --help | grep -q '\-\-enroll'

  build-deb:
    name: Build Debian Package
    needs: [fmt, clippy, test, enrollment-tests]
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get -f install -y
          sudo apt-get install -y build-essential debhelper pkg-config libsystemd-dev libssl-dev
      - name: Clean previous build artifacts
        run: |
          cargo clean
          rm -f ../linux-patch-api_*.deb
      - name: Build Debian package
        run: |
          sudo dpkg-buildpackage -us -uc -b -d
      - name: Upload to Gitea Release
        if: github.ref_type == 'tag'
        env:
          GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          FILE=$(ls ../linux-patch-api_*.deb 2>/dev/null | head -1)
          chmod +x scripts/upload-release.sh
          ./scripts/upload-release.sh "$TAG_NAME" "$FILE"

  build-deb-u2204:
    name: Build Debian Package (Ubuntu 22.04)
    needs: [fmt, clippy, test, enrollment-tests]
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get -f install -y
          sudo apt-get install -y build-essential debhelper pkg-config libsystemd-dev libssl-dev
      - name: Clean previous build artifacts
        run: |
          cargo clean
          rm -f ../linux-patch-api_*.deb
      - name: Build Debian package
        run: |
          sudo dpkg-buildpackage -us -uc -b -d
      - name: Upload to Gitea Release
        if: github.ref_type == 'tag'
        env:
          GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          FILE=$(ls ../linux-patch-api_*.deb 2>/dev/null | head -1)
          # Rename deb to include u2204 in filename to avoid collision with main build
          if [ -n "$FILE" ]; then
            U2204_FILE="$(echo "$FILE" | sed 's/_amd64/_u2204_amd64/')"
            mv "$FILE" "$U2204_FILE"
            FILE="$U2204_FILE"
          fi
          chmod +x scripts/upload-release.sh
          ./scripts/upload-release.sh "$TAG_NAME" "$FILE"

  build-rpm:
    name: Build RPM Package
    needs: [fmt, clippy, test, enrollment-tests]
    runs-on: fedora
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install build dependencies
        run: |
          sudo dnf install -y gcc rpm-build systemd-devel pkg-config openssl-devel
      - name: Clean stale RPM artifacts
        run: |
          rm -f ~/rpmbuild/RPMS/x86_64/linux-patch-api-*.rpm
          rm -f releases/linux-patch-api-*.rpm
      - name: Build release binary
        run: cargo build --release
      - name: Build RPM package
        run: |
          chmod +x build-rpm.sh
          SKIP_CARGO_BUILD=1 ./build-rpm.sh
      - name: Verify RPM package
        run: |
          VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*=.*"\([^"]*\)".*/\1/')
          RPM_FILE=$(ls ~/rpmbuild/RPMS/x86_64/linux-patch-api-${VERSION}-*.rpm 2>/dev/null | head -1)
          if [ -z "$RPM_FILE" ]; then
            echo "ERROR: RPM package not found for version $VERSION!"
            ls -la ~/rpmbuild/RPMS/x86_64/ 2>/dev/null || echo "RPM directory empty or missing"
            exit 1
          fi
          RPM_VERSION=$(rpm -qp --queryformat '%{VERSION}' "$RPM_FILE" 2>/dev/null || true)
          echo "RPM file: $RPM_FILE"
          echo "RPM version: $RPM_VERSION"
          echo "Expected version: $VERSION"
          if [ "$RPM_VERSION" != "$VERSION" ]; then
            echo "ERROR: RPM version ($RPM_VERSION) does not match expected version ($VERSION)!"
            exit 1
          fi
          echo "RPM verification passed"
      - name: Upload to Gitea Release
        if: github.ref_type == 'tag'
        env:
          GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*=.*"\([^"]*\)".*/\1/')
          FILE=$(ls ~/rpmbuild/RPMS/x86_64/linux-patch-api-${VERSION}-*.rpm 2>/dev/null | head -1)
          if [ -z "$FILE" ]; then
            echo "ERROR: No RPM found with version $VERSION for upload!"
            exit 1
          fi
          chmod +x scripts/upload-release.sh
          ./scripts/upload-release.sh "$TAG_NAME" "$FILE"

  build-apk:
    name: Build Alpine Package
    needs: [fmt, clippy, test, enrollment-tests]
    runs-on: alpine
    steps:
      - name: Checkout repository
        run: |
          apk add --no-cache curl
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          apk add --no-cache curl bash
          curl --ipv4 --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          rustup target add x86_64-unknown-linux-musl
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install build dependencies
        run: |
          apk add --no-cache alpine-sdk rust cargo openssl openssl-dev elogind-dev musl-dev abuild gcc
      - name: Build release binary
        run: cargo build --release --target x86_64-unknown-linux-musl
      - name: Build Alpine package
        run: |
          chmod +x build-alpine.sh
          SKIP_CARGO_BUILD=1 ./build-alpine.sh
      - name: Upload to Gitea Release
        if: github.ref_type == 'tag'
        env:
          GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          FILE=$(ls releases/*.apk 2>/dev/null | head -1)
          chmod +x scripts/upload-release.sh
          ./scripts/upload-release.sh "$TAG_NAME" "$FILE"

  build-arch:
    name: Build Arch Package
    needs: [fmt, clippy, test, enrollment-tests]
    runs-on: arch
    steps:
      - name: Checkout repository
        run: |
          curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
          tar -xzf repo.tar.gz --strip-components=1
          rm -f repo.tar.gz
      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
          . "$HOME/.cargo/env"
          echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
      - name: Install build dependencies
        run: |
          sudo pacman -Syu --noconfirm rust cargo systemd git base-devel gcc
      - name: Build release binary
        run: cargo build --release
      - name: Build Arch package
        run: |
          chmod +x build-arch.sh
          SKIP_CARGO_BUILD=1 ./build-arch.sh
      - name: Upload to Gitea Release
        if: startsWith(github.ref, 'refs/tags/')
        env:
          GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          FILE=$(ls releases/*.pkg.tar.zst 2>/dev/null | head -1)
          chmod +x scripts/upload-release.sh
          ./scripts/upload-release.sh "$TAG_NAME" "$FILE"
