/*
 * Copyright 2021 The Android Open Source Project
 *
 * 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
 *
 *      http://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 androidx.camera.extensions

import android.content.Context
import android.graphics.Bitmap
import android.graphics.ImageFormat
import android.graphics.SurfaceTexture
import android.util.Size
import android.view.Surface
import androidx.camera.camera2.Camera2Config
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.core.impl.utils.executor.CameraXExecutors
import androidx.camera.core.internal.compat.workaround.ExifRotationAvailability
import androidx.camera.extensions.util.ExtensionsTestUtil
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.testing.impl.CameraUtil
import androidx.camera.testing.impl.CameraUtil.PreTestCameraIdList
import androidx.camera.testing.impl.ExifUtil
import androidx.camera.testing.impl.SurfaceTextureProvider
import androidx.camera.testing.impl.SurfaceTextureProvider.SurfaceTextureCallback
import androidx.camera.testing.impl.fakes.FakeLifecycleOwner
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import org.junit.After
import org.junit.Assert.assertTrue
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.Mockito

@LargeTest
@RunWith(Parameterized::class)
@SdkSuppress(minSdkVersion = 21)
class ImageCaptureTest(
    @field:ExtensionMode.Mode @param:ExtensionMode.Mode private val extensionMode: Int,
    @field:CameraSelector.LensFacing @param:CameraSelector.LensFacing private val lensFacing: Int
) {

    @get:Rule
    val useCamera = CameraUtil.grantCameraPermissionAndPreTest(
        PreTestCameraIdList(Camera2Config.defaultConfig())
    )

    @get:Rule
    val temporaryFolder =
        TemporaryFolder(ApplicationProvider.getApplicationContext<Context>().cacheDir)

    private val context = ApplicationProvider.getApplicationContext<Context>()

    private lateinit var cameraProvider: ProcessCameraProvider

    private lateinit var extensionsManager: ExtensionsManager

    private lateinit var baseCameraSelector: CameraSelector

    private lateinit var extensionsCameraSelector: CameraSelector

    private lateinit var fakeLifecycleOwner: FakeLifecycleOwner

    @Before
    fun setUp(): Unit = runBlocking {
        assumeTrue(
            ExtensionsTestUtil.isTargetDeviceAvailableForExtensions(
                lensFacing,
                extensionMode
            )
        )

        cameraProvider = ProcessCameraProvider.getInstance(context)[10000, TimeUnit.MILLISECONDS]
        baseCameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
        extensionsManager = ExtensionsManager.getInstanceAsync(
            context,
            cameraProvider
        )[10000, TimeUnit.MILLISECONDS]

        assumeTrue(extensionsManager.isExtensionAvailable(baseCameraSelector, extensionMode))

        extensionsCameraSelector = extensionsManager.getExtensionEnabledCameraSelector(
            baseCameraSelector,
            extensionMode
        )

        withContext(Dispatchers.Main) {
            fakeLifecycleOwner = FakeLifecycleOwner().apply { startAndResume() }
        }
    }

    @After
    fun teardown(): Unit = runBlocking {
        if (::cameraProvider.isInitialized) {
            cameraProvider.shutdownAsync()[10000, TimeUnit.MILLISECONDS]
        }

        if (::extensionsManager.isInitialized) {
            extensionsManager.shutdown()[10000, TimeUnit.MILLISECONDS]
        }
    }

    companion object {
        @JvmStatic
        @get:Parameterized.Parameters(name = "extension = {0}, facing = {1}")
        val parameters: Collection<Array<Any>>
            get() = ExtensionsTestUtil.getAllExtensionsLensFacingCombinations()
    }

    @Test
    fun canBindToLifeCycleAndTakePicture(): Unit = runBlocking {
        val mockOnImageCapturedCallback = Mockito.mock(
            ImageCapture.OnImageCapturedCallback::class.java
        )

        bindAndTakePicture(mockOnImageCapturedCallback)

        // Verify the image captured.
        val imageProxy = ArgumentCaptor.forClass(
            ImageProxy::class.java
        )

        Mockito.verify(mockOnImageCapturedCallback, Mockito.timeout(5000).times(1))
            .onCaptureStarted()
        Mockito.verify(mockOnImageCapturedCallback, Mockito.timeout(10000)).onCaptureSuccess(
            imageProxy.capture()
        )
        assertThat(imageProxy.value).isNotNull()
        imageProxy.value.close() // Close the image after verification.

        // Verify the take picture should not have any error happen.
        Mockito.verify(mockOnImageCapturedCallback, Mockito.never()).onError(
            ArgumentMatchers.any(
                ImageCaptureException::class.java
            )
        )
    }

    fun canBindToLifeCycleAndTakePicture_diskIo(): Unit = runBlocking {
        val mockOnImageSavedCallback = Mockito.mock(
            ImageCapture.OnImageSavedCallback::class.java
        )

        bindAndTakePicture(mockOnImageSavedCallback)

        // Verify the image captured.
        val outputFileResults = ArgumentCaptor.forClass(
            ImageCapture.OutputFileResults::class.java
        )

        Mockito.verify(mockOnImageSavedCallback, Mockito.timeout(5000).times(1))
            .onCaptureStarted()

        Mockito.verify(mockOnImageSavedCallback, Mockito.timeout(10000)).onImageSaved(
            outputFileResults.capture()
        )
        assertThat(outputFileResults.value).isNotNull()

        // Verify the take picture should not have any error happen.
        Mockito.verify(mockOnImageSavedCallback, Mockito.never()).onError(
            ArgumentMatchers.any(
                ImageCaptureException::class.java
            )
        )
    }

    private fun isCaptureProcessProgressSupported(): Boolean = runBlocking {
        val camera = withContext(Dispatchers.Main) {
            cameraProvider.bindToLifecycle(
                fakeLifecycleOwner,
                extensionsCameraSelector
            )
        }

        val capabilities = ImageCapture.getImageCaptureCapabilities(camera.cameraInfo)
        capabilities.isCaptureProcessProgressSupported
    }

    private fun isPostviewSupported(): Boolean = runBlocking {
        val camera = withContext(Dispatchers.Main) {
            cameraProvider.bindToLifecycle(
                fakeLifecycleOwner,
                extensionsCameraSelector
            )
        }

        val capabilities = ImageCapture.getImageCaptureCapabilities(camera.cameraInfo)
        capabilities.isPostviewSupported
    }

    private suspend fun bindAndTakePicture(
        onImageCaptureCallback: ImageCapture.OnImageCapturedCallback,
        targetRotation: Int? = null,
        enablePostview: Boolean = false
    ): Camera {
        // To test bind/unbind and take picture.
        val imageCapture = ImageCapture.Builder().apply {
            targetRotation?.let { setTargetRotation(it) }
            setPostviewEnabled(enablePostview)
        }.build()
        val preview = Preview.Builder().build()
        return withContext(Dispatchers.Main) {
            // To set the update listener and Preview will change to active state.
            preview.setSurfaceProvider(
                SurfaceTextureProvider.createSurfaceTextureProvider(
                    object : SurfaceTextureCallback {
                        override fun onSurfaceTextureReady(
                            surfaceTexture: SurfaceTexture,
                            resolution: Size
                        ) {
                            // No-op.
                        }

                        override fun onSafeToRelease(
                            surfaceTexture: SurfaceTexture
                        ) {
                            // No-op.
                        }
                    })
            )

            val camera = cameraProvider.bindToLifecycle(
                fakeLifecycleOwner,
                extensionsCameraSelector,
                preview,
                imageCapture
            )

            imageCapture.takePicture(
                CameraXExecutors.mainThreadExecutor(),
                onImageCaptureCallback
            )
            camera
        }
    }

    private suspend fun bindAndTakePicture(
        onImageSavedCallback: ImageCapture.OnImageSavedCallback,
        targetRotation: Int? = null,
        enablePostview: Boolean = false
    ): Camera {
        // To test bind/unbind and take picture.
        val imageCapture = ImageCapture.Builder().apply {
            targetRotation?.let { setTargetRotation(it) }
            setPostviewEnabled(enablePostview)
        }.build()
        val preview = Preview.Builder().build()
        return withContext(Dispatchers.Main) {
            // To set the update listener and Preview will change to active state.
            preview.setSurfaceProvider(
                SurfaceTextureProvider.createSurfaceTextureProvider(
                    object : SurfaceTextureCallback {
                        override fun onSurfaceTextureReady(
                            surfaceTexture: SurfaceTexture,
                            resolution: Size
                        ) {
                            // No-op.
                        }

                        override fun onSafeToRelease(
                            surfaceTexture: SurfaceTexture
                        ) {
                            // No-op.
                        }
                    })
            )

            val camera = cameraProvider.bindToLifecycle(
                fakeLifecycleOwner,
                extensionsCameraSelector,
                preview,
                imageCapture
            )

            val saveLocation = temporaryFolder.newFile("test.jpg")
            val outputFileOptions = ImageCapture.OutputFileOptions
                .Builder(saveLocation)
                .build()
            imageCapture.takePicture(
                outputFileOptions,
                CameraXExecutors.mainThreadExecutor(),
                onImageSavedCallback
            )
            camera
        }
    }

    @Test
    fun canBindToLifeCycleAndTakePictureWithCaptureProcessProgress(): Unit = runBlocking {
        assumeTrue(isCaptureProcessProgressSupported())

        val mockOnImageCapturedCallback = Mockito.mock(
            ImageCapture.OnImageCapturedCallback::class.java
        )

        bindAndTakePicture(mockOnImageCapturedCallback)

        // Verify the image captured.
        val imageProxy = ArgumentCaptor.forClass(
            ImageProxy::class.java
        )

        Mockito.verify(mockOnImageCapturedCallback, Mockito.timeout(5000).times(1))
            .onCaptureStarted()

        Mockito.verify(mockOnImageCapturedCallback, Mockito.timeout(8000).atLeastOnce())
            .onCaptureProcessProgressed(ArgumentMatchers.anyInt())

        Mockito.verify(mockOnImageCapturedCallback, Mockito.timeout(10000)).onCaptureSuccess(
            imageProxy.capture()
        )

        assertThat(imageProxy.value).isNotNull()
        imageProxy.value.close() // Close the image after verification.

        // Verify the take picture should not have any error happen.
        Mockito.verify(mockOnImageCapturedCallback, Mockito.never()).onError(
            ArgumentMatchers.any(
                ImageCaptureException::class.java
            )
        )
    }

    @Test
    fun canBindToLifeCycleAndTakePictureWithCaptureProcessProgress_diskIo(): Unit = runBlocking {
        assumeTrue(isCaptureProcessProgressSupported())

        val mockOnImageSavedCallback = Mockito.mock(
            ImageCapture.OnImageSavedCallback::class.java
        )

        bindAndTakePicture(mockOnImageSavedCallback)

        // Verify the image captured.
        val outputFileResults = ArgumentCaptor.forClass(
            ImageCapture.OutputFileResults::class.java
        )

        Mockito.verify(mockOnImageSavedCallback, Mockito.timeout(5000).times(1))
            .onCaptureStarted()

        Mockito.verify(mockOnImageSavedCallback, Mockito.timeout(8000).atLeastOnce())
            .onCaptureProcessProgressed(ArgumentMatchers.anyInt())

        Mockito.verify(mockOnImageSavedCallback, Mockito.timeout(10000)).onImageSaved(
            outputFileResults.capture()
        )

        assertThat(outputFileResults.value).isNotNull()

        // Verify the take picture should not have any error happen.
        Mockito.verify(mockOnImageSavedCallback, Mockito.never()).onError(
            ArgumentMatchers.any(
                ImageCaptureException::class.java
            )
        )
    }

    private fun isRotationOptionSupportedDevice() =
        ExifRotationAvailability().isRotationOptionSupported

    @Test
    fun canBindToLifeCycleAndTakePictureWithPostview(): Unit = runBlocking {
        assumeTrue(isPostviewSupported())

        val captureStartedDeferred = CompletableDeferred<Boolean>()
        val captureSuccessDeferred = CompletableDeferred<ImageProxy>()
        val PostviewDeferred = CompletableDeferred<Bitmap>()
        var hasError = false
        val targetRotation = Surface.ROTATION_0

        val camera = bindAndTakePicture(object : ImageCapture.OnImageCapturedCallback() {
            override fun onError(exception: ImageCaptureException) {
                hasError = true
            }
            override fun onCaptureStarted() {
                captureStartedDeferred.complete(true)
            }
            override fun onCaptureSuccess(image: ImageProxy) {
                captureSuccessDeferred.complete(image)
            }
            override fun onPostviewBitmapAvailable(bitmap: Bitmap) {
                PostviewDeferred.complete(bitmap)
            }
        }, enablePostview = true, targetRotation = targetRotation)
        val rotationDegree = camera.cameraInfo.getSensorRotationDegrees(targetRotation)
        val isFlipped = (rotationDegree % 180) != 0

        assertThat(withTimeoutOrNull(5000) { captureStartedDeferred.await() }).isTrue()

        withTimeoutOrNull(5000) { PostviewDeferred.await() }.let {
            assertThat(it).isNotNull()
            if (isFlipped) {
                assertTrue(it!!.width <= it.height)
            } else {
                assertTrue(it!!.height <= it.width)
            }
        }

        withTimeoutOrNull(7000) { captureSuccessDeferred.await() }.use {
            assertThat(it).isNotNull()
            assertThat(it!!.format).isEqualTo(ImageFormat.JPEG)
            if (isRotationOptionSupportedDevice()) {
                val exif = ExifUtil.getExif(it)
                assertThat(exif!!.rotation).isEqualTo(it.imageInfo.rotationDegrees)
            }
        }

        assertThat(hasError).isFalse()
    }

    @Test
    fun canBindToLifeCycleAndTakePictureWithPostview_diskIo(): Unit = runBlocking {
        assumeTrue(isPostviewSupported())

        val captureStartedDeferred = CompletableDeferred<Boolean>()
        val imageSavedDeferred = CompletableDeferred<ImageCapture.OutputFileResults>()
        val PostviewDeferred = CompletableDeferred<Bitmap>()
        var hasError = false
        val targetRotation = Surface.ROTATION_0

        val camera = bindAndTakePicture(object : ImageCapture.OnImageSavedCallback {
            override fun onError(exception: ImageCaptureException) {
                hasError = true
            }
            override fun onCaptureStarted() {
                captureStartedDeferred.complete(true)
            }

            override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                imageSavedDeferred.complete(outputFileResults)
            }
            override fun onPostviewBitmapAvailable(bitmap: Bitmap) {
                PostviewDeferred.complete(bitmap)
            }
        }, enablePostview = true)
        val rotationDegree = camera.cameraInfo.getSensorRotationDegrees(targetRotation)
        val isFlipped = (rotationDegree % 180) != 0

        assertThat(withTimeoutOrNull(5000) { captureStartedDeferred.await() }).isTrue()

        withTimeoutOrNull(5000) { PostviewDeferred.await() }.let {
            assertThat(it).isNotNull()
            if (isFlipped) {
                assertTrue(it!!.width <= it.height)
            } else {
                assertTrue(it!!.height <= it.width)
            }
        }

        assertThat(withTimeoutOrNull(7000) { imageSavedDeferred.await() }).isNotNull()

        assertThat(hasError).isFalse()
    }

    @Test
    fun highResolutionDisabled_whenExtensionsEnabled(): Unit = runBlocking {
        val imageCapture = ImageCapture.Builder().build()

        withContext(Dispatchers.Main) {
            cameraProvider.bindToLifecycle(
                fakeLifecycleOwner,
                extensionsCameraSelector,
                imageCapture)
        }

        assertThat(imageCapture.currentConfig.isHigResolutionDisabled(false)).isTrue()
    }
}
