// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CAMERA_CAMERA3_TEST_CAMERA3_DEVICE_H_
#define CAMERA_CAMERA3_TEST_CAMERA3_DEVICE_H_

#include <map>
#include <memory>
#include <set>
#include <utility>
#include <vector>

#include <base/callback.h>
#include <hardware/camera3.h>

#include "camera3_test/camera3_test_gralloc.h"
#include "camera3_test/common_types.h"
#include "common/utils/common_types.h"

using cros::internal::ScopedCameraMetadata;

namespace camera3_test {

// Forward declaration
class Camera3Module;
class Camera3DeviceImpl;

class Camera3Device {
 public:
  explicit Camera3Device(int cam_id);

  ~Camera3Device();

  // Initialize the device.
  int Initialize(Camera3Module* cam_module);

  // Destroy the device.
  void Destroy();

  typedef base::Callback<void(const camera3_capture_result* result)>
      ProcessCaptureResultCallback;
  typedef base::Callback<void(const camera3_notify_msg* msg)> NotifyCallback;
  typedef base::Callback<void(uint32_t frame_number,
                              ScopedCameraMetadata metadata,
                              std::vector<ScopedBufferHandle> buffers)>
      ProcessResultMetadataOutputBuffersCallback;
  typedef base::Callback<void(
      std::vector<ScopedCameraMetadata>* partial_metadata)>
      ProcessPartialMetadataCallback;

  // Register callback function to process capture result.
  void RegisterProcessCaptureResultCallback(ProcessCaptureResultCallback cb);

  // Register callback function for notification.
  void RegisterNotifyCallback(NotifyCallback cb);

  // Register callback function to process result metadata and output buffers.
  void RegisterResultMetadataOutputBufferCallback(
      ProcessResultMetadataOutputBuffersCallback cb);

  // Register callback function to process partial metadata.
  void RegisterPartialMetadataCallback(ProcessPartialMetadataCallback cb);

  // Whether or not the template is supported.
  bool IsTemplateSupported(int32_t type);

  // Construct default request settings.
  const camera_metadata_t* ConstructDefaultRequestSettings(int type);

  // Add output stream in preparation for stream configuration.
  void AddOutputStream(int format,
                       int width,
                       int height,
                       camera3_stream_rotation_t crop_rotate_scale_degrees);

  // Add input stream in preparation for stream configuration.
  void AddInputStream(int format, int width, int height);

  // Add bidirection stream in preparation for stream configuration.
  void AddBidirectionalStream(int format, int width, int height);

  // Add output stream with raw |crop_rotate_scale_degrees| values. This
  // function should be used for testing invalid values only.
  void AddOutputStreamWithRawDegrees(int format,
                                     int width,
                                     int height,
                                     int crop_rotate_scale_degrees);

  // Configure streams and return configured streams if |streams| is not null.
  int ConfigureStreams(std::vector<const camera3_stream_t*>* streams);

  // Allocate output buffers for all configured streams and return them
  // in the stream buffer format, which has the buffer associated to the
  // corresponding stream. The allocated buffers are owned by Camera3Device.
  int AllocateOutputStreamBuffers(
      std::vector<camera3_stream_buffer_t>* output_buffers);

  // Allocate output buffers for given streams |streams| and return them
  // in the stream buffer format, which has the buffer associated to the
  // corresponding stream. The allocated buffers are owned by Camera3Device.
  int AllocateOutputBuffersByStreams(
      const std::vector<const camera3_stream_t*>& streams,
      std::vector<camera3_stream_buffer_t>* output_buffers);

  // Register buffer |unique_buffer| that is associated with the given stream
  // |stream|. Camera3Device takes buffer ownership.
  int RegisterOutputBuffer(const camera3_stream_t& stream,
                           ScopedBufferHandle unique_buffer);

  // Process given capture request |capture_request|. The frame number field of
  // |capture_request| will be overwritten if this method returns 0 on success.
  int ProcessCaptureRequest(camera3_capture_request_t* capture_request);

  // Wait for shutter with timeout. |abs_timeout| specifies an absolute timeout
  // in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000
  // (UTC), that the call should block if the shutter is immediately available.
  int WaitShutter(const struct timespec& abs_timeout);

  // Wait for capture result with timeout. |abs_timeout| specifies an absolute
  // timeout in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00
  // +0000 (UTC), that the call should block if the shutter is immediately
  // available.
  int WaitCaptureResult(const struct timespec& abs_timeout);

  // Flush all currently in-process captures and all buffers in the pipeline.
  int Flush();

  // Get static information.
  class StaticInfo;
  const StaticInfo* GetStaticInfo() const;

 private:
  std::unique_ptr<Camera3DeviceImpl> impl_;

  Camera3Device(const Camera3Device&) = delete;
  Camera3Device& operator=(const Camera3Device&) = delete;
};

class Camera3Device::StaticInfo {
 public:
  explicit StaticInfo(const camera_info& cam_info);

  // Determine whether or not all the keys are available
  bool IsKeyAvailable(uint32_t tag) const;
  bool AreKeysAvailable(std::vector<uint32_t> tags) const;

  // Whether or not the hardware level reported is at least full
  bool IsHardwareLevelAtLeastFull() const;

  // Whether or not the hardware level reported is at least external
  bool IsHardwareLevelAtLeastExternal() const;

  // Determine whether the current device supports a capability or not
  bool IsCapabilitySupported(uint8_t capability) const;

  // Check if depth output is supported, based on the depth capability
  bool IsDepthOutputSupported() const;

  // Check if standard outputs (PRIVATE, YUV, JPEG) outputs are supported,
  // based on the backwards-compatible capability
  bool IsColorOutputSupported() const;

  // Get available edge modes
  std::set<uint8_t> GetAvailableEdgeModes() const;

  // Get available noise reduction modes
  std::set<uint8_t> GetAvailableNoiseReductionModes() const;

  // Get available noise reduction modes
  std::set<uint8_t> GetAvailableColorAberrationModes() const;

  // Get available tone map modes
  std::set<uint8_t> GetAvailableToneMapModes() const;

  // Get available fps ranges
  std::set<std::pair<int32_t, int32_t>> GetAvailableFpsRanges() const;

  // Get available formats for a given direction
  // direction: ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT or
  //            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT
  std::set<int32_t> GetAvailableFormats(int32_t direction) const;

  // Check if a stream format is supported
  bool IsFormatAvailable(int format) const;

  // Get the image output resolutions in this stream configuration
  std::vector<ResolutionInfo> GetSortedOutputResolutions(int32_t format) const;

  // Get the image input resolutions in this stream configuration
  std::vector<ResolutionInfo> GetSortedInputResolutions(int32_t format) const;

  // Get the image resolutions in this stream configuration
  std::vector<ResolutionInfo> GetSortedResolutions(int32_t format,
                                                   bool is_output) const;

  // Get available input format to output format
  bool GetInputOutputConfigurationMap(
      std::map<int32_t, std::vector<int32_t>>* config_map) const;

  // Determine if camera device support AE lock control
  bool IsAELockSupported() const;

  // Determine if camera device support AWB lock control
  bool IsAWBLockSupported() const;

  // Get the maximum number of partial result a request can expect
  // Returns: maximum number of partial results; it is 1 by default.
  int32_t GetPartialResultCount() const;

  // Get the number of maximum pipeline stages a frame has to go through from
  // when it's exposed to when it's available to the framework
  // Returns: number of maximum pipeline stages on success; corresponding error
  // code on failure.
  uint8_t GetRequestPipelineMaxDepth() const;

  // Get the maximum size of JPEG image
  // Returns: maximum size of JPEG image on success; corresponding error code
  // on failure.
  int32_t GetJpegMaxSize() const;

  // Get the sensor orientation
  // Returns: degrees on success; corresponding error code on failure.
  int32_t GetSensorOrientation() const;

  // Get available thumbnail sizes
  // Returns: 0 on success; corresponding error code on failure.
  int32_t GetAvailableThumbnailSizes(
      std::vector<ResolutionInfo>* resolutions) const;

  // Get available focal lengths
  // Returns: 0 on success; corresponding error code on failure.
  int32_t GetAvailableFocalLengths(std::vector<float>* focal_lengths) const;

  // Get available apertures
  // Returns: 0 on success; corresponding error code on failure.
  int32_t GetAvailableApertures(std::vector<float>* apertures) const;

  // Get available AF modes
  // Returns: 0 on success; corresponding error code on failure.
  int32_t GetAvailableAFModes(std::vector<uint8_t>* af_modes) const;

  // Get available sensor test pattern modes
  // Returns: 0 on success; corresponding error code on failure.
  int32_t GetAvailableTestPatternModes(
      std::vector<int32_t>* test_pattern_modes) const;

  // Get max AE regions
  int32_t GetAeMaxRegions() const;

  // Get max AWB regions
  int32_t GetAwbMaxRegions() const;

  // Get max AF regions
  int32_t GetAfMaxRegions() const;

  // Get sensor pixel array size
  int32_t GetSensorPixelArraySize(uint32_t* width, uint32_t* height) const;

  // Get available request keys
  std::set<int32_t> GetAvailableRequestKeys() const;

  // Return the supported hardware level of the device, or fail if no value is
  // reported
  uint8_t GetHardwareLevel() const;

 private:
  bool IsHardwareLevelAtLeast(uint8_t level) const;

  std::set<uint8_t> GetAvailableModes(int32_t key,
                                      int32_t min_value,
                                      int32_t max_value) const;

  void GetStreamConfigEntry(camera_metadata_ro_entry_t* entry) const;

  const camera_metadata_t* characteristics_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(StaticInfo);
};

}  // namespace camera3_test

#endif  // CAMERA_CAMERA3_TEST_CAMERA3_DEVICE_H_
