/*
 * 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 android.net.Uri;
import com.google.android.gnd.persistence.local.LocalDatabaseModule;
import com.google.android.gnd.persistence.remote.RemoteStorageManager;
import com.google.android.gnd.rx.SchedulersModule;
import com.google.android.gnd.ui.util.BitmapUtil;
import com.google.android.gnd.ui.util.FileUtil;
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.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.Mockito;
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 StorageManagerTest {

  private static final int REQUEST_CODE = StorageManager.PICK_PHOTO_REQUEST_CODE;

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

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

  @Inject PermissionsManager permissionsManager;
  @Inject ActivityStreams activityStreams;
  @Inject FileUtil fileUtil;

  @Mock BitmapUtil mockBitmapUtil;
  @Mock RemoteStorageManager mockRemoteStorageManager;

  private StorageManager storageManager;

  @Before
  public void setUp() {
    hiltRule.inject();
    storageManager =
        new StorageManager(
            permissionsManager,
            activityStreams,
            mockRemoteStorageManager,
            fileUtil,
            mockBitmapUtil);
  }

  private Bitmap mockBitmap() throws IOException {
    Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8);
    Mockito.when(mockBitmapUtil.fromUri(ArgumentMatchers.any())).thenReturn(bitmap);
    return bitmap;
  }

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

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

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

  @Test
  public void testPhotoPickerResult() throws IOException {
    Bitmap mockBitmap = mockBitmap();

    TestObserver<Bitmap> subscriber = storageManager.photoPickerResult().test();

    activityStreams.onActivityResult(
        REQUEST_CODE, Activity.RESULT_OK, new Intent().setData(Uri.parse("foo")));

    subscriber.assertResult(mockBitmap);
  }
}

@@ -629,16 +629,101 @@
 ystem;%0A%0A
+import static org.mockito.ArgumentMatchers.any;%0A%0Aimport android.Manifest.permission;%0A
 import a
@@ -743,16 +743,16 @@
 tivity;%0A
-
 import a
@@ -1013,32 +1013,115 @@
 hedulersModule;%0A
+import com.google.android.gnd.system.PermissionsManager.PermissionDeniedException;%0A
 import com.googl
@@ -1415,16 +1415,49 @@
 odules;%0A
+import io.reactivex.Completable;%0A
 import i
@@ -1553,32 +1553,69 @@
 ementException;%0A
+import java8.util.function.Consumer;%0A
 import javax.inj
@@ -1734,45 +1734,8 @@
 th;%0A
-import org.mockito.ArgumentMatchers;%0A
 impo
@@ -2403,57 +2403,8 @@
 );%0A%0A
-  @Inject PermissionsManager permissionsManager;%0A
   @I
@@ -2507,16 +2507,67 @@
 apUtil;%0A
+  @Mock PermissionsManager mockPermissionsManager;%0A
   @Mock 
@@ -2774,17 +2774,21 @@
         
-p
+mockP
 ermissio
@@ -3088,70 +3088,962 @@
 Uri(
-ArgumentMatchers.any())).thenReturn(bitmap
+any(Uri.class))).thenReturn(bitmap);%0A    return bitmap;%0A  %7D%0A%0A  private void mockPermissions(boolean allow) %7B%0A    Mockito.when(mockPermissionsManager.obtainPermission(permission.READ_EXTERNAL_STORAGE))%0A        .thenReturn(%0A            allow ? Completable.complete() : Completable.error(new PermissionDeniedException()));%0A  %7D%0A%0A  @Test%0A  public void testLaunchPhotoPicker_whenPermissionGranted() %7B%0A    TestObserver%3CConsumer%3CActivity%3E%3E requests = activityStreams.getActivityRequests().test();%0A%0A    mockPermissions(true);%0A    storageManager.launchPhotoPicker().test().assertNoErrors().assertComplete(
 );%0A
+%0A
     re
-turn bitmap
+quests.assertValueCount(1);%0A  %7D%0A%0A  @Test%0A  public void testLaunchPhotoPicker_whenPermissionDenied() %7B%0A    TestObserver%3CConsumer%3CActivity%3E%3E requests = activityStreams.getActivityRequests().test();%0A%0A    mockPermissions(false);%0A    storageManager.launchPhotoPicker().test().assertFailure(PermissionDeniedException.class);%0A%0A    requests.assertNoValues()
 ;%0A  

Add tests for launchPhotoPicker