/*
 *  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.annotation.Nullable;
import android.support.test.InstrumentationRegistry;
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();
  }
}
