name: Android CI and Release

on:
  workflow_dispatch:

permissions:
  contents: write

jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      version_name: ${{ steps.app_version.outputs.version_name }}
      version_code: ${{ steps.app_version.outputs.version_code }}
      release_tag: ${{ steps.app_version.outputs.release_tag }}
      apk_name: ${{ steps.app_version.outputs.apk_name }}

    steps:
      - uses: actions/checkout@v4

      - name: Read app version
        id: app_version
        shell: bash
        run: |
          VERSION_NAME=$(sed -n 's/.*versionName = "\(.*\)".*/\1/p' app/build.gradle.kts | head -n 1)
          VERSION_CODE=$(sed -n 's/.*versionCode = \([0-9][0-9]*\).*/\1/p' app/build.gradle.kts | head -n 1)

          if [ -z "$VERSION_NAME" ] || [ -z "$VERSION_CODE" ]; then
            echo "Failed to read app version from app/build.gradle.kts"
            exit 1
          fi

          echo "version_name=$VERSION_NAME" >> "$GITHUB_OUTPUT"
          echo "version_code=$VERSION_CODE" >> "$GITHUB_OUTPUT"
          echo "release_tag=v$VERSION_NAME" >> "$GITHUB_OUTPUT"
          echo "apk_name=StreamVault-$VERSION_NAME.apk" >> "$GITHUB_OUTPUT"

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: gradle

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Prepare optional signing files
        shell: bash
        env:
          RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }}
          RELEASE_STORE_PASSWORD: ${{ secrets.RELEASE_STORE_PASSWORD }}
          RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
          RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
        run: |
          if [ -n "$RELEASE_KEYSTORE_BASE64" ] && [ -n "$RELEASE_STORE_PASSWORD" ] && [ -n "$RELEASE_KEY_ALIAS" ] && [ -n "$RELEASE_KEY_PASSWORD" ]; then
            mkdir -p keystore
            echo "$RELEASE_KEYSTORE_BASE64" | base64 --decode > keystore/release.jks
            printf '%s\n' \
              'storeFile=keystore/release.jks' \
              "storePassword=$RELEASE_STORE_PASSWORD" \
              "keyAlias=$RELEASE_KEY_ALIAS" \
              "keyPassword=$RELEASE_KEY_PASSWORD" \
              > keystore.properties
            echo "Release signing files prepared."
          else
            echo "No signing secrets configured. Building unsigned release APK."
          fi

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Run unit tests and coverage
        run: ./gradlew --console=plain testDebugUnitTest koverXmlReportCi koverHtmlReportCi

      - name: Build release APK
        run: ./gradlew --console=plain :app:assembleRelease

      - name: Prepare release artifact
        if: github.event_name == 'workflow_dispatch'
        shell: bash
        run: |
          mkdir -p dist
          APK_PATH=$(find app/build/outputs/apk/release -maxdepth 1 -name '*.apk' | head -n 1)
          if [ -z "$APK_PATH" ]; then
            echo "No release APK produced."
            exit 1
          fi
          cp "$APK_PATH" "dist/${{ steps.app_version.outputs.apk_name }}"
          cp "$APK_PATH" dist/StreamVault.apk

      - name: Upload release APK artifact
        if: github.event_name == 'workflow_dispatch'
        uses: actions/upload-artifact@v4
        with:
          name: release-apk
          path: |
            dist/${{ steps.app_version.outputs.apk_name }}
            dist/StreamVault.apk

      - name: Upload test reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-reports
          path: |
            app/build/reports/tests/
            data/build/reports/tests/
            domain/build/reports/tests/
            player/build/reports/tests/

      - name: Upload coverage reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: coverage-reports
          path: |
            build/reports/kover/

  publish-release:
    if: github.event_name == 'workflow_dispatch'
    needs: build
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Download release APK artifact
        uses: actions/download-artifact@v4
        with:
          name: release-apk
          path: dist

      - name: Read app version
        id: app_version
        shell: bash
        run: |
          VERSION_NAME=$(sed -n 's/.*versionName = "\(.*\)".*/\1/p' app/build.gradle.kts | head -n 1)
          VERSION_CODE=$(sed -n 's/.*versionCode = \([0-9][0-9]*\).*/\1/p' app/build.gradle.kts | head -n 1)

          if [ -z "$VERSION_NAME" ] || [ -z "$VERSION_CODE" ]; then
            echo "Failed to read app version from app/build.gradle.kts"
            exit 1
          fi

          echo "version_name=$VERSION_NAME" >> "$GITHUB_OUTPUT"
          echo "version_code=$VERSION_CODE" >> "$GITHUB_OUTPUT"
          echo "release_tag=v$VERSION_NAME" >> "$GITHUB_OUTPUT"
          echo "apk_name=StreamVault-$VERSION_NAME.apk" >> "$GITHUB_OUTPUT"

      - name: Extract changelog entry
        id: changelog
        shell: bash
        run: |
          VERSION="${{ steps.app_version.outputs.version_name }}"
          echo "Extracting notes for version $VERSION"
          
          # Extract lines between the header and the next header (or EOF)
          # Supports both "## [1.0.5] - date" and legacy "## 1.0.5 date" styles.
          {
            echo "notes<<EOF"
            awk -v ver="$VERSION" '
              $0 ~ ("^## \\[" ver "\\]") || $0 ~ ("^## " ver " ") { p=1; next }
              $0 ~ "^## " && p { p=0 }
              p { print }
            ' docs/CHANGELOG.md
            echo "EOF"
          } >> "$GITHUB_OUTPUT"

      - name: Publish GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: ${{ steps.app_version.outputs.release_tag }}
          name: StreamVault ${{ steps.app_version.outputs.version_name }}
          body: |
            ${{ steps.changelog.outputs.notes }}
            
            ---
            Built from `${{ github.sha }}`.
          files: |
            dist/${{ steps.app_version.outputs.apk_name }}
            dist/StreamVault.apk
          make_latest: true
          generate_release_notes: false
