#!/bin/bash
#
# SPDX-FileCopyrightText: 2020-2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-FileCopyrightText: 2026 Philipp Hasper <vcs@hasper.info>
# SPDX-FileCopyrightText: 2020-2024 Tobias Kaminsky <tobias@kaminsky.me>
# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
#
# Run instrumentation screenshot tests (record or compare) for a given test class/method.
#
# Usage:
#   ./scripts/androidScreenshotTest <record:true|false> <class-pattern> [method] [darkMode: dark|light|all] [color]
#
# Arguments:
#   record         "true" to record/update reference screenshots (-Precord), "false" to compare.
#   class name     the first matching .java or .kt file under app/src/androidTest/java is passed to the instrumentation runner
#   method name    optional test method name to run (appends #method to class). If not given, the entire class's tests run
#   darkMode       optional: dark | light | all  (if "all", the script runs scripts/runAllScreenshotCombinations).
#   color          optional value passed as COLOR to the instrumentation runner, for testing different color themes
#
# Behavior notes:
#   - Temporarily sets is_beta to true in app/src/main/res/values/setup.xml and restores it afterwards.
#   - Searches for or launches an emulator AVD named "uiComparison" and sets ANDROID_SERIAL for the run.
#   - Requires adb and emulator on PATH and the repo's ./gradlew wrapper.
#   - Caution: If interrupted the setup.xml change may remain; revert with:
#     git checkout -- app/src/main/res/values/setup.xml
#
# Examples:
#   ./scripts/androidScreenshotTest false MyScreenshotTest
#   ./scripts/androidScreenshotTest true MyScreenshotTest testCaptureAll all
#   ./scripts/androidScreenshotTest false MyScreenshotTest "" dark red
# END_DOCUMENTATION
set -e

if [ $# -lt 2 ]; then
    # Print the documentation from the file header, up until END_DOCUMENTATION, excluding specific lines
    sed -n '2,/^#[[:space:]]*END_DOCUMENTATION/ {
      /^#[[:space:]]*SPDX-FileCopyrightText/ d
      /^#[[:space:]]*SPDX-License-Identifier/ d
      /^#[[:space:]]*END_DOCUMENTATION/ d
      s/^#//
      p
    }' "$0" | sed '/^$/d'
    exit
fi

pushd app/src/androidTest/java

class=$(find | grep $2 | grep -E "java$|kt$" | head -n1|sed s'/\//\./'g | sed s'#^\.\.##' | sed s'#\.java##'| sed s'#\.kt##')

if [[ -z $class ]]; then
    echo "Class not found!"
    exit 1
fi

cd ../../../

if [ $1 == "true" ] ; then
    record="-Precord"
else
    record=""
fi

if [ -e $3 ] ; then
    method=""
else
    method="#$3"

    # check if method exists
    if [[ $(grep -c $3 $(find | grep $2 | grep -E "java$|kt$" | head -n1)) -eq 0 ]]; then
        echo "Method not found!"
        exit 1
    fi
fi

if [ -e $4 ] ; then
    darkMode=""
else
    darkMode="-Pandroid.testInstrumentationRunnerArguments.DARKMODE=$4"
fi

popd
sed -i s'#<bool name="is_beta">false</bool>#<bool name="is_beta">true</bool>#'g app/src/main/res/values/setup.xml

# check if emulator is running
emulatorIsRunning=false
while read line ; do
    if [[ $(adb -s $line emu avd name 2>/dev/null | head -n1) =~ uiComparison.* ]]; then
        emulatorIsRunning=true
        export ANDROID_SERIAL=$line
        break
    fi
done < <(adb devices | cut -f1)

if [ "$emulatorIsRunning" == false ] ; then
    if [ -z "$(command -v emulator || true)" ]; then
        echo "emulator not found in PATH; typically located in Android/sdk/emulator" >&2
        exit 1
    fi
    if [ -z "$(command -v avdmanager || true)" ]; then
        echo "avdmanager not found in PATH; typically located in Android/sdk/cmdline-tools/latest/bin" >&2
        exit 1
    fi
    # If emulator of expected name doesn't exist, create it
    # TODO - this was copied from updateScreenshots.sh - move it to a common helper script
    if [[ $(emulator -list-avds | grep uiComparison -c) -eq 0 ]]; then
        (sleep 5; echo "no") | avdmanager create avd -n uiComparison -c 100M -k "system-images;android-28;google_apis;x86" --abi "google_apis/x86"
    fi

    "$(command -v emulator)" -writable-system -avd uiComparison -no-snapshot -gpu swiftshader_indirect -no-audio -skin 500x833 &
    sleep 20
fi

if [ -e $5 ] ; then
    color=""
else
    color="-Pandroid.testInstrumentationRunnerArguments.COLOR=$5"
fi

if [[ $4 = "all" ]]; then
    scripts/runAllScreenshotCombinations "noCI" "$1" "-Pandroid.testInstrumentationRunnerArguments.class=$class$method"
else
    SHOT_TEST=true ./gradlew  genericDebugExecuteScreenshotTests $record \
    -Dorg.gradle.jvmargs="--add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.nio.channels=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED" \
    -Pscreenshot=true \
    -Pandroid.testInstrumentationRunnerArguments.annotation=com.owncloud.android.utils.ScreenshotTest \
    -Pandroid.testInstrumentationRunnerArguments.class=$class$method \
    $darkMode \
    $color
fi


sed -i s'#<bool name="is_beta">true</bool>#<bool name="is_beta">false</bool>#'g app/src/main/res/values/setup.xml
unset ANDROID_SERIAL
