name: Build Main

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6.0.2

      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            openssl \
            pkg-config \
            libxml2-dev \
            libsqlite3-dev \
            llvm \
            clang

      - name: Setup Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Cache cargo registry
        uses: actions/cache@v5.0.3
        with:
          path: ~/.cargo/registry
          key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-registry-

      - name: Cache cargo index
        uses: actions/cache@v5.0.3
        with:
          path: ~/.cargo/git
          key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-git-

      - name: Cache cargo build
        uses: actions/cache@v5.0.3
        with:
          path: target
          key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-build-target-

      - name: Run cargo fmt
        run: cargo fmt --check

      - name: Run clippy
        run: cargo clippy --all-targets --all-features -- -D warnings

  test:
    name: Test
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - name: Checkout code
        uses: actions/checkout@v6.0.2

      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            openssl \
            pkg-config \
            libxml2-dev \
            libsqlite3-dev \
            llvm \
            clang

      - name: Setup Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Cache cargo registry
        uses: actions/cache@v5.0.3
        with:
          path: ~/.cargo/registry
          key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-registry-

      - name: Cache cargo index
        uses: actions/cache@v5.0.3
        with:
          path: ~/.cargo/git
          key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-git-

      - name: Cache cargo build
        uses: actions/cache@v5.0.3
        with:
          path: target
          key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-build-target-

      - name: Run cargo test
        run: cargo test --all-features

  build_musl:
    name: Build MUSL targets
    needs: [lint, test]
    strategy:
      matrix:
        include:
          - docker-tag: x86_64-musl
            target: x86_64-unknown-linux-musl
          - docker-tag: aarch64-musl
            target: aarch64-unknown-linux-musl
          - docker-tag: armv7-musleabihf
            target: armv7-unknown-linux-musleabihf
    runs-on: ubuntu-latest
    container: ghcr.io/blackdex/rust-musl:${{ matrix.docker-tag }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v6.0.2
      - name: Build
        run: |
          cargo build --release

      - name: Create package directory
        run: |
          mkdir -p package/eilmeldung
          cp target/${{ matrix.target }}/release/eilmeldung package/eilmeldung/
          cp -r examples package/eilmeldung/

      - name: Create tarball
        run: |
          cd package
          tar -czf eilmeldung-${{ matrix.target }}-latest.tar.gz eilmeldung/

      - name: Upload artifact
        uses: actions/upload-artifact@v7.0.0
        with:
          name: eilmeldung-${{ matrix.target }}-latest
          path: package/eilmeldung-${{ matrix.target }}-latest.tar.gz
          retention-days: 30


  build_macos:
    name: Build ${{ matrix.target }}
    runs-on: ${{ matrix.os}}
    needs: [lint, test]
    strategy:
      matrix:
        include:
          - os: macos-latest
            target: x86_64-apple-darwin
          - os: macos-latest
            target: aarch64-apple-darwin
    steps:
      - name: Checkout code
        uses: actions/checkout@v6.0.2

      - name: Install system dependencies (Ubuntu Linux)
        if: ${{ runner.os == 'Linux' }}
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            openssl \
            pkg-config \
            libxml2-dev \
            libsqlite3-dev \
            llvm \
            clang

      - name: Install system dependencies (macOS)
        if: ${{ runner.os == 'macOS' }}
        run: |
          brew install libxml2

      - name: Setup Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target  }}

      - name: Cache cargo registry
        uses: actions/cache@v5.0.3
        with:
          path: ~/.cargo/registry
          key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-registry-

      - name: Cache cargo index
        uses: actions/cache@v5.0.3
        with:
          path: ~/.cargo/git
          key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-git-

      - name: Cache cargo build
        uses: actions/cache@v5.0.3
        with:
          path: target
          key: ${{ runner.os }}-cargo-build-target-release-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-build-target-release-

      - name: Build release binary
        run: cargo build --release --target ${{ matrix.target  }}
        env:
          PKG_CONFIG_PATH: ${{ matrix.target == 'x86_64-apple-darwin' && '/usr/local/opt/libxml2/lib/pkgconfig:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/pkgconfig' || (runner.os == 'macOS' && '/opt/homebrew/opt/libxml2/lib/pkgconfig' || '') }}
          PKG_CONFIG_ALLOW_CROSS: ${{ runner.os == 'macOS' && '1' || '' }}
          XML2_CONFIG: ${{ matrix.target == 'x86_64-apple-darwin' && '/Library/Developer/CommandLineTools/usr/bin/xml2-config' || '' }}

      - name: Create package directory
        run: |
          mkdir -p package/eilmeldung
          cp target/${{ matrix.target }}/release/eilmeldung package/eilmeldung/
          cp -r examples package/eilmeldung/

      - name: Create tarball
        run: |
          cd package
          tar -czf eilmeldung-${{ matrix.target }}-latest.tar.gz eilmeldung/

      - name: Upload artifact
        uses: actions/upload-artifact@v7.0.0
        with:
          name: eilmeldung-${{ matrix.target }}-latest
          path: package/eilmeldung-${{ matrix.target }}-latest.tar.gz
          retention-days: 30


  build_windows:
    name: Build x86_64-pc-windows-msvc
    runs-on: windows-latest
    needs: [lint, test]
    steps:
      - name: Checkout code
        uses: actions/checkout@v6.0.2

      - name: Install vcpkg dependencies
        run: vcpkg install libxml2:x64-windows-static
        shell: pwsh

      - name: Setup Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-pc-windows-msvc

      - name: Cache cargo registry
        uses: actions/cache@v5.0.3
        with:
          path: ~\.cargo\registry
          key: windows-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: windows-cargo-registry-

      - name: Cache cargo index
        uses: actions/cache@v5.0.3
        with:
          path: ~\.cargo\git
          key: windows-cargo-git-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: windows-cargo-git-

      - name: Build release binary
        run: cargo build --release --target x86_64-pc-windows-msvc
        env:
          RUSTFLAGS: "-C target-feature=+crt-static"
          VCPKG_ROOT: C:\vcpkg
          VCPKGRS_DYNAMIC: "0"
          PKG_CONFIG_PATH: C:\vcpkg\installed\x64-windows-static\lib\pkgconfig
          CMAKE_TOOLCHAIN_FILE: C:\vcpkg\scripts\buildsystems\vcpkg.cmake
          VCPKG_TARGET_TRIPLET: x64-windows-static
          OPENSSL_SRC_PERL: C:\Strawberry\perl\bin\perl.exe

      - name: Create package directory
        run: |
          mkdir -p package/eilmeldung
          cp target/x86_64-pc-windows-msvc/release/eilmeldung.exe package/eilmeldung/
          cp -r examples package/eilmeldung/
        shell: bash

      - name: Create archive
        run: |
          cd package
          tar -czf eilmeldung-x86_64-pc-windows-msvc-latest.tar.gz eilmeldung/
        shell: bash

      - name: Upload artifact
        uses: actions/upload-artifact@v7.0.0
        with:
          name: eilmeldung-x86_64-pc-windows-msvc-latest
          path: package/eilmeldung-x86_64-pc-windows-msvc-latest.tar.gz
          retention-days: 30
