/*
 *  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 android.media.MediaRecorder;

/**
 * Base interface for camera1 and camera2 implementations. Extends VideoCapturer with a
 * switchCamera() function. Also provides subinterfaces for handling camera events, and a helper
 * class for detecting camera freezes.
 */
public interface CameraVideoCapturer extends VideoCapturer {
  /**
   * Camera events handler - can be used to be notifed about camera events. The callbacks are
   * executed from an arbitrary thread.
   */
  public interface CameraEventsHandler {
    // Camera error handler - invoked when camera can not be opened
    // or any camera exception happens on camera thread.
    void onCameraError(String errorDescription);

    // Called when camera is disconnected.
    void onCameraDisconnected();

    // Invoked when camera stops receiving frames.
    void onCameraFreezed(String errorDescription);

    // Callback invoked when camera is opening.
    void onCameraOpening(String cameraName);

    // Callback invoked when first camera frame is available after camera is started.
    void onFirstFrameAvailable();

    // Callback invoked when camera is closed.
    void onCameraClosed();
  }

  /**
   * Camera switch handler - one of these functions are invoked with the result of switchCamera().
   * The callback may be called on an arbitrary thread.
   */
  public interface CameraSwitchHandler {
    // Invoked on success. |isFrontCamera| is true if the new camera is front facing.
    void onCameraSwitchDone(boolean isFrontCamera);

    // Invoked on failure, e.g. camera is stopped or only one camera available.
    void onCameraSwitchError(String errorDescription);
  }

  /**
   * Switch camera to the next valid camera id. This can only be called while the camera is running.
   * This function can be called from any thread.
   */
  void switchCamera(CameraSwitchHandler switchEventsHandler);

  /**
   * MediaRecorder add/remove handler - one of these functions are invoked with the result of
   * addMediaRecorderToCamera() or removeMediaRecorderFromCamera calls.
   * The callback may be called on an arbitrary thread.
   */
  public interface MediaRecorderHandler {
    // Invoked on success.
    void onMediaRecorderSuccess();

    // Invoked on failure, e.g. camera is stopped or any exception happens.
    void onMediaRecorderError(String errorDescription);
  }

  /**
   * Add MediaRecorder to camera pipeline. This can only be called while the camera is running.
   * Once MediaRecorder is added to camera pipeline camera switch is not allowed.
   * This function can be called from any thread.
   */
  void addMediaRecorderToCamera(MediaRecorder mediaRecorder, MediaRecorderHandler resultHandler);

  /**
   * Remove MediaRecorder from camera pipeline. This can only be called while the camera is running.
   * This function can be called from any thread.
   */
  void removeMediaRecorderFromCamera(MediaRecorderHandler resultHandler);

  /**
   * Helper class to log framerate and detect if the camera freezes. It will run periodic callbacks
   * on the SurfaceTextureHelper thread passed in the ctor, and should only be operated from that
   * thread.
   */
  public static class CameraStatistics {
    private final static String TAG = "CameraStatistics";
    private final static int CAMERA_OBSERVER_PERIOD_MS = 2000;
    private final static int CAMERA_FREEZE_REPORT_TIMOUT_MS = 4000;

    private final SurfaceTextureHelper surfaceTextureHelper;
    private final CameraEventsHandler eventsHandler;
    private int frameCount;
    private int freezePeriodCount;
    // Camera observer - monitors camera framerate. Observer is executed on camera thread.
    private final Runnable cameraObserver = new Runnable() {
      @Override
      public void run() {
        final int cameraFps = Math.round(frameCount * 1000.0f / CAMERA_OBSERVER_PERIOD_MS);
        Logging.d(TAG, "Camera fps: " + cameraFps + ".");
        if (frameCount == 0) {
          ++freezePeriodCount;
          if (CAMERA_OBSERVER_PERIOD_MS * freezePeriodCount >= CAMERA_FREEZE_REPORT_TIMOUT_MS
              && eventsHandler != null) {
            Logging.e(TAG, "Camera freezed.");
            if (surfaceTextureHelper.isTextureInUse()) {
              // This can only happen if we are capturing to textures.
              eventsHandler.onCameraFreezed("Camera failure. Client must return video buffers.");
            } else {
              eventsHandler.onCameraFreezed("Camera failure.");
            }
            return;
          }
        } else {
          freezePeriodCount = 0;
        }
        frameCount = 0;
        surfaceTextureHelper.getHandler().postDelayed(this, CAMERA_OBSERVER_PERIOD_MS);
      }
    };

    public CameraStatistics(
        SurfaceTextureHelper surfaceTextureHelper, CameraEventsHandler eventsHandler) {
      if (surfaceTextureHelper == null) {
        throw new IllegalArgumentException("SurfaceTextureHelper is null");
      }
      this.surfaceTextureHelper = surfaceTextureHelper;
      this.eventsHandler = eventsHandler;
      this.frameCount = 0;
      this.freezePeriodCount = 0;
      surfaceTextureHelper.getHandler().postDelayed(cameraObserver, CAMERA_OBSERVER_PERIOD_MS);
    }

    private void checkThread() {
      if (Thread.currentThread() != surfaceTextureHelper.getHandler().getLooper().getThread()) {
        throw new IllegalStateException("Wrong thread");
      }
    }

    public void addFrame() {
      checkThread();
      ++frameCount;
    }

    public void release() {
      surfaceTextureHelper.getHandler().removeCallbacks(cameraObserver);
    }
  }
}
