package org.whoneedhelp.mobile;

import static org.junit.Assert.fail;

import android.Manifest;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RunWith(AndroidJUnit4.class)
public final class TrackingProcessDeathProbeTest {
    @Test
    public void startsNonStickyTrackingForExternalProcessKill() throws Exception {
        Context context = ApplicationProvider.getApplicationContext();
        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        String packageName = context.getPackageName();

        context.stopService(new Intent(context, TrackingService.class));
        context.getSystemService(NotificationManager.class).cancelAll();
        device.executeShellCommand(
            "pm grant " + packageName + " " + Manifest.permission.ACCESS_FINE_LOCATION
        );

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            device.executeShellCommand(
                "pm grant " + packageName + " " + Manifest.permission.POST_NOTIFICATIONS
            );
        }

        Intent intent = TrackingService.startIntent(
            context,
            UUID.randomUUID().toString(),
            "process-death-csrf",
            "_session=process-death"
        );

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }

        // The host harness kills this exact process after observing the active
        // service and notification. Reaching the deadline means the harness did
        // not perform the required process-death probe.
        TimeUnit.SECONDS.sleep(30);
        fail("The external process-death harness did not kill the tracking process");
    }
}
