name: CI

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

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  test:
    name: Test on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]

    steps:
      - uses: actions/checkout@v4

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

      - name: Cache cargo + target
        uses: Swatinem/rust-cache@v2

      - name: Check formatting
        run: cargo fmt --all -- --check

      - name: Run clippy
        run: cargo clippy -- -D warnings

      - name: Run tests
        run: cargo test

      - name: Build in release mode
        run: cargo build --release

  cross-build:
    name: Cross-build for ${{ matrix.target }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-latest
          - target: x86_64-apple-darwin
            os: macos-latest
          - target: aarch64-apple-darwin
            os: macos-latest
          - target: x86_64-pc-windows-msvc
            os: windows-latest
          - target: aarch64-pc-windows-msvc
            os: windows-latest

    steps:
      - uses: actions/checkout@v4

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

      - name: Cache cargo + target
        uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

      - name: Add Linux cross dependencies
        if: matrix.target == 'aarch64-unknown-linux-gnu'
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu
          echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV

      - name: Cross-build
        run: cargo build --release --target ${{ matrix.target }}

  shell-smoke:
    name: Shell smoke (${{ matrix.shell }})
    runs-on: windows-latest
    needs: test
    strategy:
      fail-fast: false
      matrix:
        shell: [pwsh, bash]
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable

      - name: Cache cargo + target
        uses: Swatinem/rust-cache@v2
        with:
          key: shell-smoke

      - name: Build release binary
        run: cargo build --release

      - name: Verify PowerShell completion loads
        if: matrix.shell == 'pwsh'
        shell: pwsh
        run: |
          $script = & ./target/release/cc-switch.exe completion powershell | Out-String
          Invoke-Expression $script

      - name: Verify Bash completion loads
        if: matrix.shell == 'bash'
        shell: bash
        run: |
          ./target/release/cc-switch.exe completion bash > /tmp/cc.bash
          bash -c "source /tmp/cc.bash"

      - name: CRUD round-trip (PowerShell)
        if: matrix.shell == 'pwsh'
        shell: pwsh
        run: |
          ./target/release/cc-switch.exe add ci-test -t sk-test -u https://example.com
          ./target/release/cc-switch.exe list
          ./target/release/cc-switch.exe remove ci-test

      - name: CRUD round-trip (Bash)
        if: matrix.shell == 'bash'
        shell: bash
        run: |
          ./target/release/cc-switch.exe add ci-test -t sk-test -u https://example.com
          ./target/release/cc-switch.exe list
          ./target/release/cc-switch.exe remove ci-test

  security-audit:
    name: Security Audit
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable

      - name: Cache cargo + target
        uses: Swatinem/rust-cache@v2
        with:
          key: security-audit

      - name: Install cargo-audit
        run: cargo install cargo-audit

      - name: Run cargo audit
        run: cargo audit

  coverage:
    name: Code Coverage
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable

      - name: Cache cargo + target
        uses: Swatinem/rust-cache@v2
        with:
          key: coverage

      - name: Install cargo-tarpaulin
        run: cargo install cargo-tarpaulin

      - name: Run coverage
        run: cargo tarpaulin --out Xml

      - name: Upload to codecov
        uses: codecov/codecov-action@v3
        with:
          file: ./cobertura.xml
          fail_ci_if_error: true
          token: ${{secrets.CODECOV_TOKEN}}
