name: CI

on:
  push:
    branches:
      - master
      - ci
  pull_request:
    branches:
      - "*"

jobs:
  lint: 
    name: Rustfmt + Clippy
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt,clippy
      - run: |
          cargo fmt --all -- --check
          cargo clippy

  android:
    name: Check (android)
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt,clippy
      - name: Setup Java JDK
        uses: actions/setup-java@v4.5.0
        with:
          java-version: '17'
          distribution: 'temurin'
      - name: Setup Android SDK
        uses: android-actions/setup-android@v3
      - name: Add android rust target
        run: rustup target add aarch64-linux-android
      - name: Install Cargo NDK
        run: cargo install cargo-ndk
      - name: Run tests
        run: make jni-check

  linux-test:
    name: Test (Linux)
    uses: ./.github/workflows/build-and-test.yml
    with:
      os: ubuntu-22.04
      additional-setup: |
        sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libspeechd-dev libxkbcommon-dev libssl-dev

  macos-test:
    name: Test (macOS)
    uses: ./.github/workflows/build-and-test.yml
    with:
      os: macos-latest

  windows-test:
    name: Test (Windows)
    uses: ./.github/workflows/build-and-test.yml
    with:
      os: windows-latest

  packaging:
    name: rpm/deb
    runs-on: ubuntu-22.04
    needs: linux-test
    if: github.ref_name == 'master' || github.ref_name == 'ci'

    strategy:
      fail-fast: false
      matrix:
        arch: [x86_64, aarch64]

    steps:
      # Checkout the repository
      - name: Checkout Code
        uses: actions/checkout@v4

      # Install Packaging Tools
      - name: Install Packaging Tools
        run: |
          sudo apt-get update
          if [ "${{ matrix.arch }}" != "$(uname -m)" ]; then
            sudo apt-get install -y gcc-${{ matrix.arch }}-linux-gnu g++-aarch64-linux-gnu
            rustup target add ${{ matrix.arch }}-unknown-linux-gnu
          fi
          cargo install cargo-generate-rpm cargo-deb

      - name: Build Cross (${{ matrix.arch }})
        if: matrix.arch != runner.arch
        run: cargo build --release --target=${{ matrix.arch }}-unknown-linux-gnu

      - name: Build Native (${{ matrix.arch }})
        if: matrix.arch == runner.arch
        run: cargo build --release

      - name: Build RPM (Cross)
        if: matrix.arch != runner.arch
        run: cargo generate-rpm -p crates/notedeck_chrome --target=${{ matrix.arch }}-unknown-linux-gnu

      - name: Build RPM
        if: matrix.arch == runner.arch
        run: cargo generate-rpm -p crates/notedeck_chrome

      - name: Build deb (Cross)
        if: matrix.arch != runner.arch
        run: cargo deb -p notedeck_chrome --target=${{ matrix.arch }}-unknown-linux-gnu

      - name: Build deb
        if: matrix.arch == runner.arch
        run: cargo deb -p notedeck_chrome

      - name: Upload RPM
        uses: actions/upload-artifact@v4
        if: runner.arch == matrix.arch
        with:
          name: notedeck-${{ matrix.arch }}.rpm
          path: target/release/generate-rpm/notedeck.rpm

      - name: Upload RPM (Cross)
        uses: actions/upload-artifact@v4
        if: runner.arch != matrix.arch
        with:
          name: notedeck-${{ matrix.arch }}.rpm
          path: target/${{ matrix.arch }}-unknown-linux-gnu/generate-rpm/*.rpm

      - name: Upload deb (Native)
        uses: actions/upload-artifact@v4
        if: runner.arch == matrix.arch
        with:
          name: notedeck-${{ matrix.arch }}.deb
          path: target/release/debian/notedeck.deb

      # Upload Debian Package (Cross)
      - name: Upload deb (Cross)
        uses: actions/upload-artifact@v4
        if: runner.arch != matrix.arch
        with:
          name: notedeck-${{ matrix.arch }}.deb
          path: target/${{ matrix.arch }}-unknown-linux-gnu/debian/*.deb

  macos-dmg:
    name: macOS dmg
    runs-on: macos-latest
    needs: macos-test
    if: github.ref_name == 'master' || github.ref_name == 'ci'
    env:
      NOTEDECK_APPLE_RELEASE_CERT_ID: ${{ secrets.NOTEDECK_APPLE_RELEASE_CERT_ID }}
      NOTEDECK_RELEASE_APPLE_ID: ${{ secrets.NOTEDECK_RELEASE_APPLE_ID }}
      NOTEDECK_APPLE_APP_SPECIFIC_PW: ${{ secrets.NOTEDECK_APPLE_APP_SPECIFIC_PW }}
      NOTEDECK_APPLE_TEAM_ID: ${{ secrets.NOTEDECK_APPLE_TEAM_ID }}

    strategy:
      fail-fast: false
      matrix:
        arch: [x86_64, aarch64]

    steps:
      # Checkout the repository
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Install Required Tools
        run: |
          brew install create-dmg
          cargo install cargo-bundle
          rustup target add ${{ matrix.arch }}-apple-darwin

      - name: Import apple codesign cert
        uses: apple-actions/import-codesign-certs@v3
        with: 
          p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
          p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}

      - name: Rust cache
        uses: Swatinem/rust-cache@v2

      - name: Run macOS DMG Build Script
        run: ARCH=${{ matrix.arch }} ./scripts/macos_build.sh

      - name: Upload DMG Artifact
        uses: actions/upload-artifact@v4
        with:
          name: notedeck-${{ matrix.arch }}.dmg
          path: packages/notedeck-${{ matrix.arch }}.dmg

  windows-installer:
    name: Windows Installer
    runs-on: windows-latest
    needs: windows-test
    if: github.ref_name == 'master' || github.ref_name == 'ci'
    strategy:
      fail-fast: false
      matrix:
        arch: [x86_64, aarch64]

    steps:
      # Checkout the repository
      - name: Checkout Code
        uses: actions/checkout@v4

      # Build cache
      - name: Rust cache
        uses: Swatinem/rust-cache@v2

      # Build
      - name: Build (Native Only)
        run: cargo build --release

      # Create packages directory
      - name: Create packages directory
        run: mkdir packages

      # Install Inno Setup
      - name: Install Inno Setup
        run: choco install innosetup --no-progress --yes

      # Set up Rust toolchain
      - name: Install Rust toolchain
        run: rustup target add ${{ matrix.arch }}-pc-windows-msvc

      # Build
      - name: Build
        shell: pwsh
        run: |
          $target = "${{ matrix.arch }}-pc-windows-msvc"
          Write-Output "Building for target: $target"
          cargo build --release --target=$target

      # Generate ISS Script
      - name: Generate Inno Setup Script
        shell: pwsh
        run: |
          $arch = "${{ matrix.arch }}"
          $issContent = @"
          [Setup]
          AppName=Damus Notedeck
          AppVersion=0.1
          DefaultDirName={pf}\Notedeck
          DefaultGroupName=Damus Notedeck
          OutputDir=..\packages\$arch
          OutputBaseFilename=DamusNotedeckInstaller
          Compression=lzma
          SolidCompression=yes

          [Files]
          Source: "..\target\$arch-pc-windows-msvc\release\notedeck.exe"; DestDir: "{app}"; Flags: ignoreversion

          [Icons]
          Name: "{group}\Damus Notedeck"; Filename: "{app}\notedeck.exe"

          [Run]
          Filename: "{app}\notedeck.exe"; Description: "Launch Damus Notedeck"; Flags: nowait postinstall skipifsilent
          "@
          Set-Content -Path "scripts/windows-installer-$arch.iss" -Value $issContent

      # Build Installer
      - name: Run Inno Setup Script
        run: |
          & "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "scripts\windows-installer-${{ matrix.arch }}.iss"

      # Move output
      - name: Move Inno Script outputs to architecture-specific folder
        run: |
          New-Item -ItemType Directory -Force -Path packages\${{ matrix.arch }}
          Move-Item -Path packages\${{ matrix.arch }}\DamusNotedeckInstaller.exe -Destination packages\${{ matrix.arch }}\DamusNotedeckInstaller.exe
      # Upload the installer as an artifact
      - name: Upload Installer
        uses: actions/upload-artifact@v4
        with:
          name: DamusNotedeckInstaller-${{ matrix.arch }}.exe
          path: packages\${{ matrix.arch }}\DamusNotedeckInstaller.exe

  upload-artifacts:
    name: Upload Artifacts to Server
    runs-on: ubuntu-22.04
    needs: [packaging, macos-dmg, windows-installer]
    if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/ci'

    steps:
      - name: Download all Artifacts
        uses: actions/download-artifact@v4

      - name: Setup SSH and Upload
        run: |
          eval "$(ssh-agent -s)"
          mkdir -p ~/.ssh
          chmod 700 ~/.ssh
          echo "${{ secrets.DEPLOY_SFTP_KEY }}" | tr -d '\r' | ssh-add -
          echo "${{ secrets.DEPLOY_IP }} ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEN65pj1cNMqlf96jZLr1i9+mnHIN4jjRPPTDix6sRnt" >> ~/.ssh/known_hosts
          ls -la /home/runner/work/notedeck/notedeck/notedeck-x86_64.rpm
          export ARTIFACTS=/home/runner/work/notedeck/notedeck
          sftp ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_IP }} <<EOF
          cd upload/artifacts
          put $ARTIFACTS/notedeck-x86_64.rpm/*
          put $ARTIFACTS/notedeck-x86_64.deb/*
          put $ARTIFACTS/notedeck-x86_64.dmg/*
          put $ARTIFACTS/notedeck-aarch64.rpm/*
          put $ARTIFACTS/notedeck-aarch64.deb/*
          put $ARTIFACTS/notedeck-aarch64.dmg/*
          put $ARTIFACTS/DamusNotedeckInstaller-x86_64.exe/*
          put $ARTIFACTS/DamusNotedeckInstaller-aarch64.exe/*
          bye
          EOF

