/*
 * 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 android.camera.cts.api31test;

import static android.hardware.camera2.cts.CameraTestUtils.*;

import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.cts.CameraTestUtils;
import android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
import android.hardware.camera2.cts.helpers.CameraErrorCollector;
import android.hardware.camera2.cts.helpers.StaticMetadata;
import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.test.AndroidTestCase;
import android.util.Log;
import android.util.Size;
import android.view.Surface;

import com.android.compatibility.common.util.CddTest;
import com.android.ex.camera2.blocking.BlockingSessionCallback;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import static junit.framework.Assert.*;
import static org.mockito.Mockito.*;

public class SPerfClassTest extends AndroidTestCase {
    private static final String TAG = "SPerfClassTest";
    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);

    private static final Size FULLHD = new Size(1920, 1080);
    private static final Size VGA = new Size(640, 480);
    private static final int CONFIGURE_TIMEOUT = 5000; //ms
    private static final int CAPTURE_TIMEOUT = 1500; //ms

    private CameraManager mCameraManager;
    private String[] mCameraIds;
    private Handler mHandler;
    private HandlerThread mHandlerThread;
    private CameraErrorCollector mCollector;

    @Override
    public void setContext(Context context) {
        super.setContext(context);
        mCameraManager = context.getSystemService(CameraManager.class);
        assertNotNull("Can't connect to camera manager!", mCameraManager);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        mCameraIds = mCameraManager.getCameraIdList();
        assertNotNull("Camera ids shouldn't be null", mCameraIds);

        mHandlerThread = new HandlerThread(TAG);
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());

        mCollector = new CameraErrorCollector();
    }

    @Override
    protected void tearDown() throws Exception {
        mHandlerThread.quitSafely();
        mHandler = null;

        try {
            mCollector.verify();
        } catch (Throwable e) {
            // When new Exception(e) is used, exception info will be printed twice.
            throw new Exception(e.getMessage());
        } finally {
            super.tearDown();
        }
    }

    // Verify primary camera devices's supported JPEG sizes are at least 1080p.
    private void testSPerfClassJpegSizesByCamera(String cameraId) throws Exception {
        boolean isPrimaryRear = CameraTestUtils.isPrimaryRearFacingCamera(
                mCameraManager, cameraId);
        boolean isPrimaryFront = CameraTestUtils.isPrimaryFrontFacingCamera(
                mCameraManager, cameraId);
        if (!isPrimaryRear && !isPrimaryFront) {
            return;
        }

        CameraCharacteristics c = mCameraManager.getCameraCharacteristics(cameraId);
        StaticMetadata staticInfo = new StaticMetadata(c, CheckLevel.ASSERT, mCollector);

        Size[] jpegSizes = staticInfo.getJpegOutputSizesChecked();
        assertTrue("Primary cameras must support JPEG formats",
                jpegSizes != null && jpegSizes.length > 0);
        for (Size jpegSize : jpegSizes) {
            mCollector.expectTrue(
                    "Primary camera's JPEG size must be at least 1080p, but is " +
                    jpegSize,
                    jpegSize.getWidth() >= FULLHD.getWidth() &&
                    jpegSize.getHeight() >= FULLHD.getHeight());
        }

        CameraDevice camera = null;
        ImageReader jpegTarget = null;
        Image image = null;
        try {
            camera = CameraTestUtils.openCamera(mCameraManager, cameraId,
                    /*listener*/null, mHandler);

            List<OutputConfiguration> outputConfigs = new ArrayList<>();
            SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
            jpegTarget = CameraTestUtils.makeImageReader(VGA,
                    ImageFormat.JPEG, 1 /*maxNumImages*/, imageListener, mHandler);
            Surface jpegSurface = jpegTarget.getSurface();
            outputConfigs.add(new OutputConfiguration(jpegSurface));

            // isSessionConfigurationSupported will return true for JPEG sizes smaller
            // than 1080P, due to framework rouding up to closest supported size (1080p).
            SessionConfigSupport sessionConfigSupport = isSessionConfigSupported(
                    camera, mHandler, outputConfigs, /*inputConfig*/ null,
                    SessionConfiguration.SESSION_REGULAR, true/*defaultSupport*/);
            mCollector.expectTrue("isSessionConfiguration fails with error",
                    !sessionConfigSupport.error);
            mCollector.expectTrue("isSessionConfiguration returns false for JPEG < 1080p",
                    sessionConfigSupport.configSupported);

            // Session creation for JPEG sizes smaller than 1080p will succeed, and the
            // result JPEG image dimension is rounded up to closest supported size (1080p).
            CaptureRequest.Builder request =
                    camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            request.addTarget(jpegSurface);


            CameraCaptureSession.StateCallback sessionListener =
                    mock(CameraCaptureSession.StateCallback.class);
            CameraCaptureSession session = configureCameraSessionWithConfig(
                    camera, outputConfigs, sessionListener, mHandler);

            verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()).
                    onConfigured(any(CameraCaptureSession.class));
            verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()).
                    onReady(any(CameraCaptureSession.class));
            verify(sessionListener, never()).onConfigureFailed(any(CameraCaptureSession.class));
            verify(sessionListener, never()).onActive(any(CameraCaptureSession.class));
            verify(sessionListener, never()).onClosed(any(CameraCaptureSession.class));

            CameraCaptureSession.CaptureCallback captureListener =
                    mock(CameraCaptureSession.CaptureCallback.class);
            session.capture(request.build(), captureListener, mHandler);

            verify(captureListener, timeout(CAPTURE_TIMEOUT).atLeastOnce()).
                    onCaptureCompleted(any(CameraCaptureSession.class),
                            any(CaptureRequest.class), any(TotalCaptureResult.class));
            verify(captureListener, never()).onCaptureFailed(any(CameraCaptureSession.class),
                    any(CaptureRequest.class), any(CaptureFailure.class));

            image = imageListener.getImage(CAPTURE_TIMEOUT);
            assertNotNull("Image must be valid", image);
            assertEquals("Image format isn't JPEG", image.getFormat(), ImageFormat.JPEG);

            byte[] data = CameraTestUtils.getDataFromImage(image);
            assertTrue("Invalid image data", data != null && data.length > 0);

            CameraTestUtils.validateJpegData(data, FULLHD.getWidth(), FULLHD.getHeight(),
                    null /*filePath*/);
        } finally {
            if (camera != null) {
                camera.close();
            }
            if (jpegTarget != null) {
                jpegTarget.close();
            }
            if (image != null) {
                image.close();
            }
        }
    }

    /**
     * Check JPEG size overrides for devices claiming S Performance class requirement via
     * Version.MEDIA_PERFORMANCE_CLASS
     */
    public void testSPerfClassJpegSizes() throws Exception {
        final boolean isAtLeastSPerfClass =
                (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= Build.VERSION_CODES.S);
        if (!isAtLeastSPerfClass) {
            return;
        }

        for (int i = 0; i < mCameraIds.length; i++) {
            testSPerfClassJpegSizesByCamera(mCameraIds[i]);
        }
    }
}
