/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.gnd.system;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import com.google.android.gnd.persistence.local.LocalDatabaseModule;
import com.google.android.gnd.rx.SchedulersModule;
import dagger.hilt.android.testing.HiltAndroidRule;
import dagger.hilt.android.testing.HiltAndroidTest;
import dagger.hilt.android.testing.HiltTestApplication;
import dagger.hilt.android.testing.UninstallModules;
import io.reactivex.observers.TestObserver;
import java.io.IOException;
import java.util.NoSuchElementException;
import javax.inject.Inject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@SuppressWarnings("unchecked")
@HiltAndroidTest
@UninstallModules({SchedulersModule.class, LocalDatabaseModule.class})
@Config(application = HiltTestApplication.class)
@RunWith(RobolectricTestRunner.class)
public class CameraManagerTest {

  private static final int REQUEST_CODE = CameraManager.CAPTURE_PHOTO_REQUEST_CODE;

  @Rule public MockitoRule rule = MockitoJUnit.rule();

  @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this);

  @Inject PermissionsManager permissionsManager;
  @Inject ActivityStreams activityStreams;

  private CameraManager cameraManager;

  @Before
  public void setUp() {
    hiltRule.inject();
    cameraManager = new CameraManager(permissionsManager, activityStreams);
  }

  @Test
  public void testCapturePhotoResult_nullIntent() {
    TestObserver<Bitmap> subscriber = cameraManager.capturePhotoResult().test();
    activityStreams.onActivityResult(REQUEST_CODE, Activity.RESULT_OK, null);
    subscriber.assertFailure(NoSuchElementException.class);
  }

  @Test
  public void testCapturePhotoResult_emptyExtras() {
    TestObserver<Bitmap> subscriber = cameraManager.capturePhotoResult().test();
    activityStreams.onActivityResult(REQUEST_CODE, Activity.RESULT_OK, new Intent());
    subscriber.assertFailure(NoSuchElementException.class);
  }

  @Test
  public void testCapturePhotoResult_requestCancelled() {
    TestObserver<Bitmap> subscriber = cameraManager.capturePhotoResult().test();
    activityStreams.onActivityResult(REQUEST_CODE, Activity.RESULT_CANCELED, null);
    subscriber.assertResult();
  }

  @Test
  public void testPhotoPickerResult() throws IOException {
    Bitmap mockBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8);

    TestObserver<Bitmap> subscriber = cameraManager.capturePhotoResult().test();

    activityStreams.onActivityResult(
        REQUEST_CODE, Activity.RESULT_OK, new Intent().putExtra("data", mockBitmap));

    subscriber.assertResult(mockBitmap);
  }
}

@@ -629,16 +629,52 @@
 ystem;%0A%0A
+import android.Manifest.permission;%0A
 import a
@@ -694,16 +694,16 @@
 tivity;%0A
-
 import a
@@ -873,24 +873,107 @@
 lersModule;%0A
+import com.google.android.gnd.system.PermissionsManager.PermissionDeniedException;%0A
 import dagge
@@ -1173,16 +1173,49 @@
 odules;%0A
+import io.reactivex.Completable;%0A
 import i
@@ -1311,32 +1311,69 @@
 ementException;%0A
+import java8.util.function.Consumer;%0A
 import javax.inj
@@ -1488,16 +1488,69 @@
 unWith;%0A
+import org.mockito.Mock;%0Aimport org.mockito.Mockito;%0A
 import o
@@ -2161,22 +2161,20 @@
 s);%0A%0A  @
-Inject
+Mock
  Permiss
@@ -2185,17 +2185,21 @@
 Manager 
-p
+mockP
 ermissio
@@ -2392,43 +2392,1066 @@
 ger(
-permissionsManager, activityStreams
+mockPermissionsManager, activityStreams);%0A  %7D%0A%0A  private void mockPermissions(boolean allow) %7B%0A    String%5B%5D permissions = %7Bpermission.WRITE_EXTERNAL_STORAGE, permission.CAMERA%7D;%0A    for (String permission : permissions) %7B%0A      Mockito.when(mockPermissionsManager.obtainPermission(permission))%0A          .thenReturn(%0A              allow ? Completable.complete() : Completable.error(new PermissionDeniedException()));%0A    %7D%0A  %7D%0A%0A  @Test%0A  public void testLaunchPhotoCapture_whenPermissionGranted() %7B%0A    TestObserver%3CConsumer%3CActivity%3E%3E requests = activityStreams.getActivityRequests().test();%0A%0A    mockPermissions(true);%0A    cameraManager.launchPhotoCapture().test().assertNoErrors().assertComplete();%0A%0A    requests.assertValueCount(1);%0A  %7D%0A%0A  @Test%0A  public void testLaunchPhotoCapture_whenPermissionDenied() %7B%0A    TestObserver%3CConsumer%3CActivity%3E%3E requests = activityStreams.getActivityRequests().test();%0A%0A    mockPermissions(false);%0A    cameraManager.launchPhotoCapture().test().assertFailure(PermissionDeniedException.class);%0A%0A    requests.assertNoValues(
 );%0A 

Add tests for launchPhotoCapture