/*
 *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import static org.junit.Assert.fail;

import android.annotation.TargetApi;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.os.Handler;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import androidx.annotation.Nullable;
import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import java.util.concurrent.CountDownLatch;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@TargetApi(21)
@RunWith(BaseJUnit4ClassRunner.class)
public class Camera2CapturerTest {
  static final String TAG = "Camera2CapturerTest";

  /**
   * Simple camera2 implementation that only knows how to open the camera and close it.
   */
  private class SimpleCamera2 {
    final CameraManager cameraManager;
    final LooperThread looperThread;
    final CountDownLatch openDoneSignal;
    final Object cameraDeviceLock;
    @Nullable CameraDevice cameraDevice; // Guarded by cameraDeviceLock
    boolean openSucceeded; // Guarded by cameraDeviceLock

    private class LooperThread extends Thread {
      final CountDownLatch startedSignal = new CountDownLatch(1);
      private Handler handler;

      @Override
      public void run() {
        Looper.prepare();
        handler = new Handler();
        startedSignal.countDown();
        Looper.loop();
      }

      public void waitToStart() {
        ThreadUtils.awaitUninterruptibly(startedSignal);
      }

      public void requestStop() {
        handler.getLooper().quit();
      }

      public Handler getHandler() {
        return handler;
      }
    }

    private class CameraStateCallback extends CameraDevice.StateCallback {
      @Override
      public void onClosed(CameraDevice cameraDevice) {
        Logging.d(TAG, "Simple camera2 closed.");

        synchronized (cameraDeviceLock) {
          SimpleCamera2.this.cameraDevice = null;
        }
      }

      @Override
      public void onDisconnected(CameraDevice cameraDevice) {
        Logging.d(TAG, "Simple camera2 disconnected.");

        synchronized (cameraDeviceLock) {
          SimpleCamera2.this.cameraDevice = null;
        }
      }

      @Override
      public void onError(CameraDevice cameraDevice, int errorCode) {
        Logging.w(TAG, "Simple camera2 error: " + errorCode);

        synchronized (cameraDeviceLock) {
          SimpleCamera2.this.cameraDevice = cameraDevice;
          openSucceeded = false;
        }

        openDoneSignal.countDown();
      }

      @Override
      public void onOpened(CameraDevice cameraDevice) {
        Logging.d(TAG, "Simple camera2 opened.");

        synchronized (cameraDeviceLock) {
          SimpleCamera2.this.cameraDevice = cameraDevice;
          openSucceeded = true;
        }

        openDoneSignal.countDown();
      }
    }

    SimpleCamera2(Context context, String deviceName) {
      cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
      looperThread = new LooperThread();
      looperThread.start();
      looperThread.waitToStart();
      cameraDeviceLock = new Object();
      openDoneSignal = new CountDownLatch(1);
      cameraDevice = null;
      Logging.d(TAG, "Opening simple camera2.");
      try {
        cameraManager.openCamera(deviceName, new CameraStateCallback(), looperThread.getHandler());
      } catch (CameraAccessException e) {
        fail("Simple camera2 CameraAccessException: " + e.getMessage());
      }

      Logging.d(TAG, "Waiting for simple camera2 to open.");
      ThreadUtils.awaitUninterruptibly(openDoneSignal);
      synchronized (cameraDeviceLock) {
        if (!openSucceeded) {
          fail("Opening simple camera2 failed.");
        }
      }
    }

    public void close() {
      Logging.d(TAG, "Closing simple camera2.");
      synchronized (cameraDeviceLock) {
        if (cameraDevice != null) {
          cameraDevice.close();
        }
      }

      looperThread.requestStop();
      ThreadUtils.joinUninterruptibly(looperThread);
    }
  }

  private class TestObjectFactory extends CameraVideoCapturerTestFixtures.TestObjectFactory {
    @Override
    public CameraEnumerator getCameraEnumerator() {
      return new Camera2Enumerator(getAppContext());
    }

    @Override
    public Context getAppContext() {
      return InstrumentationRegistry.getTargetContext();
    }

    @SuppressWarnings("deprecation")
    @Override
    public Object rawOpenCamera(String cameraName) {
      return new SimpleCamera2(getAppContext(), cameraName);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void rawCloseCamera(Object camera) {
      ((SimpleCamera2) camera).close();
    }
  }

  private CameraVideoCapturerTestFixtures fixtures;

  @Before
  public void setUp() {
    fixtures = new CameraVideoCapturerTestFixtures(new TestObjectFactory());
  }

  @After
  public void tearDown() {
    fixtures.dispose();
  }

  @Test
  @SmallTest
  public void testCreateAndDispose() throws InterruptedException {
    fixtures.createCapturerAndDispose();
  }

  @Test
  @SmallTest
  public void testCreateNonExistingCamera() throws InterruptedException {
    fixtures.createNonExistingCamera();
  }

  // This test that the camera can be started and that the frames are forwarded
  // to a Java video renderer using a "default" capturer.
  // It tests both the Java and the C++ layer.
  @Test
  @MediumTest
  public void testCreateCapturerAndRender() throws InterruptedException {
    fixtures.createCapturerAndRender();
  }

  // This test that the camera can be started and that the frames are forwarded
  // to a Java video renderer using the front facing video capturer.
  // It tests both the Java and the C++ layer.
  @Test
  @MediumTest
  public void testStartFrontFacingVideoCapturer() throws InterruptedException {
    fixtures.createFrontFacingCapturerAndRender();
  }

  // This test that the camera can be started and that the frames are forwarded
  // to a Java video renderer using the back facing video capturer.
  // It tests both the Java and the C++ layer.
  @Test
  @MediumTest
  public void testStartBackFacingVideoCapturer() throws InterruptedException {
    fixtures.createBackFacingCapturerAndRender();
  }

  // This test that the default camera can be started and that the camera can
  // later be switched to another camera.
  // It tests both the Java and the C++ layer.
  @Test
  @MediumTest
  public void testSwitchVideoCapturer() throws InterruptedException {
    fixtures.switchCamera();
  }

  @Test
  @MediumTest
  public void testSwitchVideoCapturerToSpecificCameraName() throws InterruptedException {
    fixtures.switchCamera(true /* specifyCameraName */);
  }

  @Test
  @MediumTest
  public void testCameraEvents() throws InterruptedException {
    fixtures.cameraEventsInvoked();
  }

  // Test what happens when attempting to call e.g. switchCamera() after camera has been stopped.
  @Test
  @MediumTest
  public void testCameraCallsAfterStop() throws InterruptedException {
    fixtures.cameraCallsAfterStop();
  }

  // This test that the VideoSource that the CameraVideoCapturer is connected to can
  // be stopped and restarted. It tests both the Java and the C++ layer.
  @Test
  @LargeTest
  public void testStopRestartVideoSource() throws InterruptedException {
    fixtures.stopRestartVideoSource();
  }

  // This test that the camera can be started at different resolutions.
  // It does not test or use the C++ layer.
  @Test
  @LargeTest
  public void testStartStopWithDifferentResolutions() throws InterruptedException {
    fixtures.startStopWithDifferentResolutions();
  }

  // This test what happens if buffers are returned after the capturer have
  // been stopped and restarted. It does not test or use the C++ layer.
  @Test
  @LargeTest
  public void testReturnBufferLate() throws InterruptedException {
    fixtures.returnBufferLate();
  }

  // This test that we can capture frames, keep the frames in a local renderer, stop capturing,
  // and then return the frames. The difference between the test testReturnBufferLate() is that we
  // also test the JNI and C++ AndroidVideoCapturer parts.
  @Test
  @MediumTest
  public void testReturnBufferLateEndToEnd() throws InterruptedException {
    fixtures.returnBufferLateEndToEnd();
  }

  // This test that CameraEventsHandler.onError is triggered if video buffers are not returned to
  // the capturer.
  @Test
  @LargeTest
  public void testCameraFreezedEventOnBufferStarvation() throws InterruptedException {
    fixtures.cameraFreezedEventOnBufferStarvation();
  }

  // This test that frames forwarded to a renderer is scaled if adaptOutputFormat is
  // called. This test both Java and C++ parts of of the stack.
  @Test
  @MediumTest
  public void testScaleCameraOutput() throws InterruptedException {
    fixtures.scaleCameraOutput();
  }

  // This test that frames forwarded to a renderer is cropped to a new orientation if
  // adaptOutputFormat is called in such a way. This test both Java and C++ parts of of the stack.
  @Test
  @MediumTest
  public void testCropCameraOutput() throws InterruptedException {
    fixtures.cropCameraOutput();
  }

  // This test that an error is reported if the camera is already opened
  // when CameraVideoCapturer is started.
  @Test
  @LargeTest
  public void testStartWhileCameraIsAlreadyOpen() throws InterruptedException {
    fixtures.startWhileCameraIsAlreadyOpen();
  }

  // This test that CameraVideoCapturer can be started, even if the camera is already opened
  // if the camera is closed while CameraVideoCapturer is re-trying to start.
  @Test
  @LargeTest
  public void testStartWhileCameraIsAlreadyOpenAndCloseCamera() throws InterruptedException {
    fixtures.startWhileCameraIsAlreadyOpenAndCloseCamera();
  }

  // This test that CameraVideoCapturer.stop can be called while CameraVideoCapturer is
  // re-trying to start.
  @Test
  @MediumTest
  public void testStartWhileCameraIsAlreadyOpenAndStop() throws InterruptedException {
    fixtures.startWhileCameraIsAlreadyOpenAndStop();
  }
}
