/*
 * Copyright 2019 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.integration.extensions;

import static androidx.camera.testing.SurfaceTextureProvider.createSurfaceTextureProvider;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;

import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;

import android.app.Instrumentation;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Size;

import androidx.annotation.NonNull;
import androidx.annotation.experimental.UseExperimental;
import androidx.camera.camera2.Camera2Config;
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.Preview;
import androidx.camera.core.impl.CaptureProcessor;
import androidx.camera.core.impl.PreviewConfig;
import androidx.camera.core.internal.CameraUseCaseAdapter;
import androidx.camera.extensions.AutoImageCaptureExtender;
import androidx.camera.extensions.AutoPreviewExtender;
import androidx.camera.extensions.BeautyImageCaptureExtender;
import androidx.camera.extensions.BeautyPreviewExtender;
import androidx.camera.extensions.BokehImageCaptureExtender;
import androidx.camera.extensions.BokehPreviewExtender;
import androidx.camera.extensions.ExtensionsManager;
import androidx.camera.extensions.HdrImageCaptureExtender;
import androidx.camera.extensions.HdrPreviewExtender;
import androidx.camera.extensions.ImageCaptureExtender;
import androidx.camera.extensions.NightImageCaptureExtender;
import androidx.camera.extensions.NightPreviewExtender;
import androidx.camera.extensions.PreviewExtender;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.GLUtil;
import androidx.camera.testing.SurfaceTextureProvider;
import androidx.camera.testing.TimestampCaptureProcessor;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;

import com.google.common.util.concurrent.ListenableFuture;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * Tests that the {@link androidx.camera.extensions.impl.PreviewImageProcessorImpl} properly
 * populates the timestamp for the {@link SurfaceTexture}.
 */
@MediumTest
@RunWith(Parameterized.class)
public class PreviewProcessorTimestampTest {

    @Rule
    public TestRule mUseCamera = CameraUtil.grantCameraPermissionAndPreTest();

    private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
    private final Context mContext = ApplicationProvider.getApplicationContext();

    private ExtensionsManager.EffectMode mEffectMode;
    @CameraSelector.LensFacing
    private int mLensFacing;
    private CountDownLatch mInputTimestampsLatch;
    private CountDownLatch mOutputTimestampsLatch;
    private CountDownLatch mSurfaceTextureLatch;
    private Set<Long> mInputTimestamps = new HashSet<>();
    private Set<Long> mOutputTimestamps = new HashSet<>();

    TimestampCaptureProcessor.TimestampListener mTimestampListener;
    SurfaceTexture.OnFrameAvailableListener mOnFrameAvailableListener;

    private ImageCapture.Builder mImageCaptureBuilder;
    private Preview.Builder mPreviewBuilder;

    @Parameterized.Parameters(name = "effect = {0}, facing = {1}")
    public static Collection<Object[]> getParameters() {
        return Arrays.asList(new Object[][]{
                {ExtensionsManager.EffectMode.BOKEH, CameraSelector.LENS_FACING_FRONT},
                {ExtensionsManager.EffectMode.BOKEH, CameraSelector.LENS_FACING_BACK},
                {ExtensionsManager.EffectMode.HDR, CameraSelector.LENS_FACING_FRONT},
                {ExtensionsManager.EffectMode.HDR, CameraSelector.LENS_FACING_BACK},
                {ExtensionsManager.EffectMode.BEAUTY, CameraSelector.LENS_FACING_FRONT},
                {ExtensionsManager.EffectMode.BEAUTY, CameraSelector.LENS_FACING_BACK},
                {ExtensionsManager.EffectMode.NIGHT, CameraSelector.LENS_FACING_FRONT},
                {ExtensionsManager.EffectMode.NIGHT, CameraSelector.LENS_FACING_BACK},
                {ExtensionsManager.EffectMode.AUTO, CameraSelector.LENS_FACING_FRONT},
                {ExtensionsManager.EffectMode.AUTO, CameraSelector.LENS_FACING_BACK}
        });
    }

    public PreviewProcessorTimestampTest(ExtensionsManager.EffectMode effectMode,
            @CameraSelector.LensFacing int lensFacing) {
        mEffectMode = effectMode;
        mLensFacing = lensFacing;
    }

    @Before
    @UseExperimental(markerClass = ExperimentalCamera2Interop.class)
    public void setUp() throws Exception {
        mProcessingHandlerThread =
                new HandlerThread("Processing");
        mProcessingHandlerThread.start();
        mProcessingHandler = new Handler(mProcessingHandlerThread.getLooper());

        assumeTrue(androidx.camera.testing.CameraUtil.deviceHasCamera());

        CameraXConfig config = Camera2Config.defaultConfig();
        CameraX.initialize(mContext, config);

        ListenableFuture<ExtensionsManager.ExtensionsAvailability> availability =
                ExtensionsManager.init(mContext);
        ExtensionsManager.ExtensionsAvailability extensionsAvailability = availability.get(1,
                TimeUnit.SECONDS);
        assumeTrue(extensionsAvailability
                == ExtensionsManager.ExtensionsAvailability.LIBRARY_AVAILABLE);

        mImageCaptureBuilder = new ImageCapture.Builder();
        mPreviewBuilder = new Preview.Builder();
        mInputTimestampsLatch = new CountDownLatch(1);

        mTimestampListener = new TimestampCaptureProcessor.TimestampListener() {
            boolean mComplete = false;

            @Override
            public void onTimestampAvailable(long timestamp) {
                if (mComplete) {
                    return;
                }

                mInputTimestamps.add(timestamp);
                if (mInputTimestamps.size() > 10) {
                    mInputTimestampsLatch.countDown();
                    mComplete = true;
                }
            }
        };

        mOutputTimestampsLatch = new CountDownLatch(1);

        mOnFrameAvailableListener = new SurfaceTexture.OnFrameAvailableListener() {
            boolean mComplete = false;

            @Override
            public void onFrameAvailable(SurfaceTexture surfaceTexture) {
                if (mComplete) {
                    return;
                }

                synchronized (mIsSurfaceTextureReleasedLock) {
                    if (!mIsSurfaceTextureReleased) {
                        mInstrumentation.runOnMainSync(() -> {
                            surfaceTexture.updateTexImage();
                        });
                    }
                }

                mOutputTimestamps.add(surfaceTexture.getTimestamp());
                if (mOutputTimestamps.size() > 10) {
                    mOutputTimestampsLatch.countDown();
                    mComplete = true;
                }
            }
        };

        mSurfaceTextureLatch = new CountDownLatch(1);
    }

    @After
    public void cleanUp() throws InterruptedException, ExecutionException, TimeoutException {
        CameraX.shutdown().get(10000, TimeUnit.MILLISECONDS);
        ExtensionsManager.deinit().get();
    }

    private HandlerThread mProcessingHandlerThread;
    private Handler mProcessingHandler;

    private boolean mIsSurfaceTextureReleased = false;
    private Object mIsSurfaceTextureReleasedLock = new Object();

    @Test
    public void timestampIsCorrect() throws InterruptedException {
        assumeTrue(androidx.camera.testing.CameraUtil.hasCameraWithLensFacing(mLensFacing));
        assumeTrue(ExtensionsManager.isExtensionAvailable(mEffectMode, mLensFacing));

        enableExtension(mEffectMode, mLensFacing);

        // To test bind/unbind and take picture.
        ImageCapture imageCapture = mImageCaptureBuilder.build();

        PreviewConfig previewConfig = mPreviewBuilder.getUseCaseConfig();
        CaptureProcessor previewCaptureProcessor = previewConfig.getCaptureProcessor(null);
        assumeNotNull(previewCaptureProcessor);
        mPreviewBuilder.setCaptureProcessor(
                new TimestampCaptureProcessor(previewCaptureProcessor, mTimestampListener));

        Preview preview = mPreviewBuilder.build();

        CameraSelector cameraSelector =
                new CameraSelector.Builder().requireLensFacing(mLensFacing).build();
        mInstrumentation.runOnMainSync(() -> {
            // To set the update listener and Preview will change to active state.
            preview.setSurfaceProvider(createSurfaceTextureProvider(
                    new SurfaceTextureProvider.SurfaceTextureCallback() {
                        @Override
                        public void onSurfaceTextureReady(@NonNull SurfaceTexture surfaceTexture,
                                @NonNull Size resolution) {
                            surfaceTexture.attachToGLContext(GLUtil.getTexIdFromGLContext());
                            surfaceTexture.setOnFrameAvailableListener(
                                    mOnFrameAvailableListener, mProcessingHandler);
                            mSurfaceTextureLatch.countDown();
                        }

                        @Override
                        public void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture) {
                            synchronized (mIsSurfaceTextureReleasedLock) {
                                mIsSurfaceTextureReleased = true;
                                surfaceTexture.release();
                            }
                        }
                    }));

            CameraUseCaseAdapter cameraUseCaseAdapter =
                    CameraUtil.createCameraUseCaseAdapter(mContext, cameraSelector);
            try {
                cameraUseCaseAdapter.addUseCases(Arrays.asList(preview, imageCapture));
            } catch (CameraUseCaseAdapter.CameraException e) {
                e.printStackTrace();
            }
        });

        assertTrue(mSurfaceTextureLatch.await(1000, TimeUnit.MILLISECONDS));

        assertTrue(mInputTimestampsLatch.await(1000, TimeUnit.MILLISECONDS));
        assertTrue(mOutputTimestampsLatch.await(1000, TimeUnit.MILLISECONDS));

        assertEquals(mInputTimestamps, mOutputTimestamps);
    }

    /**
     * To invoke the enableExtension() method for different effect.
     */
    private void enableExtension(ExtensionsManager.EffectMode effectMode,
            @CameraSelector.LensFacing int lensFacing) {

        CameraSelector cameraSelector =
                new CameraSelector.Builder().requireLensFacing(lensFacing).build();

        ImageCaptureExtender imageCaptureExtender = null;
        PreviewExtender previewExtender = null;

        switch (effectMode) {
            case HDR:
                imageCaptureExtender = HdrImageCaptureExtender.create(mImageCaptureBuilder);
                previewExtender = HdrPreviewExtender.create(mPreviewBuilder);
                break;
            case BOKEH:
                imageCaptureExtender = BokehImageCaptureExtender.create(mImageCaptureBuilder);
                previewExtender = BokehPreviewExtender.create(mPreviewBuilder);
                break;
            case BEAUTY:
                imageCaptureExtender = BeautyImageCaptureExtender.create(mImageCaptureBuilder);
                previewExtender = BeautyPreviewExtender.create(mPreviewBuilder);
                break;
            case NIGHT:
                imageCaptureExtender = NightImageCaptureExtender.create(mImageCaptureBuilder);
                previewExtender = NightPreviewExtender.create(mPreviewBuilder);
                break;
            case AUTO:
                imageCaptureExtender = AutoImageCaptureExtender.create(mImageCaptureBuilder);
                previewExtender = AutoPreviewExtender.create(mPreviewBuilder);
                break;
        }

        assertNotNull(imageCaptureExtender);
        assertNotNull(previewExtender);

        assertTrue(previewExtender.isExtensionAvailable(cameraSelector));
        previewExtender.enableExtension(cameraSelector);
        assertTrue(imageCaptureExtender.isExtensionAvailable(cameraSelector));
        imageCaptureExtender.enableExtension(cameraSelector);
    }
}
