// Copyright 2020 The Fuchsia 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 SRC_CAMERA_BIN_CAMERA_GYM_STREAM_CYCLER_H_
#define SRC_CAMERA_BIN_CAMERA_GYM_STREAM_CYCLER_H_

#include <fuchsia/camera3/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fit/function.h>
#include <lib/fpromise/result.h>

#include <gtest/gtest_prod.h>

#include "fuchsia/camera/gym/cpp/fidl.h"
#include "fuchsia/math/cpp/fidl.h"
#include "src/camera/bin/camera-gym/moving_window.h"

namespace camera {

// This class is responsible for exercising the camera APIs to cycle between the various streams and
// configurations reported by a camera.
class StreamCycler {
 public:
  ~StreamCycler();
  static fpromise::result<std::unique_ptr<StreamCycler>, zx_status_t> Create(
      fuchsia::camera3::DeviceWatcherHandle watcher, fuchsia::sysmem::AllocatorHandle allocator,
      async_dispatcher_t* dispatcher, bool manual_mode);
  using AddCollectionHandler = fit::function<uint32_t(fuchsia::sysmem::BufferCollectionTokenHandle,
                                                      fuchsia::sysmem::ImageFormat_2, std::string)>;
  using RemoveCollectionHandler = fit::function<void(uint32_t)>;
  using ShowBufferHandler =
      fit::function<void(uint32_t, uint32_t, zx::eventpair*, std::optional<fuchsia::math::RectF>)>;
  using MuteStateHandler = fit::function<void(bool)>;
  // Registers handlers that are called when the cycler adds or removes a buffer collection. The
  // value returned by |on_add_collection| will be subsequently passed to |on_remove_collection|.
  void SetHandlers(AddCollectionHandler on_add_collection,
                   RemoveCollectionHandler on_remove_collection, ShowBufferHandler on_show_buffer,
                   MuteStateHandler on_mute_changed);

  using CommandStatusHandler =
      fit::function<void(fuchsia::camera::gym::Controller_SendCommand_Result)>;

  void set_controller_dispatcher(async_dispatcher_t* dispatcher) {
    controller_dispatcher_ = dispatcher;
  }

  // Manual mode entry points:
  void ExecuteCommand(fuchsia::camera::gym::Command command, CommandStatusHandler handler);

  void set_auto_cycle_interval(std::optional<zx::duration> interval) {
    auto_cycle_interval_ = interval;
  }

 private:
  explicit StreamCycler(async_dispatcher_t* dispatcher, bool manual_mode = false);

  // Notification to camera-gym that the camera device is present.
  void WatchDevicesCallback(std::vector<fuchsia::camera3::WatchDevicesEvent> events);

  // Notification to camera-gym that the mute state has changed.
  void WatchMuteStateHandler(bool software_muted, bool hardware_muted);

  // Forcibly select the stream config for the next demo cycle. This has an intended side effect of
  // disconnecting all current streams, which should trigger the RemoveCollectionHandler's for the
  // existing streams.
  void ForceNextStreamConfiguration();

  // Notification to camera-gym that the stream configuration has changed.
  void WatchCurrentConfigurationCallback(uint32_t config_index);

  // Kick off the sequence to connect all of the streams for this demo cycle.
  void ConnectToAllStreams();

  // Kick off the sequence to connect a single stream.
  void ConnectToStream(uint32_t config_index, uint32_t stream_index);

  // Notification to camera-gym that the crop region has been set.
  void WatchCropRegionCallback(uint32_t stream_index, std::unique_ptr<fuchsia::math::RectF> region);

  // Next camera frame on given stream is available.
  void OnNextFrame(uint32_t stream_index, fuchsia::camera3::FrameInfo2 frame_info);

  // Disconnect a single stream.
  void DisconnectStream(uint32_t stream_index);

  // Utility to return what the next config_index should be.
  uint32_t NextConfigIndex();

  // LateChecker: Update the timestamp because a new frame arrived.
  void ResetStreamWatchdog(uint32_t stream_index);

  // LateChecker: Restart all watchdog timers
  // For purposes like the start of streaming, etc.
  void ResetAllWatchdogs();

  // LateChecker: See if any frame arrival deadlines expired.
  void CheckAllWatchdogs();

  // Manual mode entry points:
  void PostedExecuteCommand(fuchsia::camera::gym::Command command, CommandStatusHandler handler);

  void ExecuteSetConfigCommand(fuchsia::camera::gym::SetConfigCommand& command);
  void ExecuteAddStreamCommand(fuchsia::camera::gym::AddStreamCommand& command);
  void ExecuteSetCropCommand(fuchsia::camera::gym::SetCropCommand& command);
  void ExecuteSetResolutionCommand(fuchsia::camera::gym::SetResolutionCommand& command);

  // When a command successfully executes, CommandSuccessNotify must be called.
  void CommandSuccessNotify();

  // When a command experiences any failure in execution, CommandFailureNotify must be called.
  void CommandFailureNotify(::fuchsia::camera::gym::CommandError status);

  async_dispatcher_t* dispatcher_;
  async_dispatcher_t* controller_dispatcher_;
  fuchsia::camera3::DeviceWatcherPtr watcher_;
  fuchsia::sysmem::AllocatorPtr allocator_;
  fuchsia::camera3::DevicePtr device_;
  std::vector<fuchsia::camera3::Configuration2> configurations_;

  bool manual_mode_;
  std::optional<zx::duration> auto_cycle_interval_;

  // Are the camera streams currently muted?
  bool muted_ = false;

  // Only set by WatchCurrentConfigurationCallback().
  // Only used by ConnectToAllStreams() and NextConfigIndex().
  // Set to the config_index AFTER being notified that the config was set by the driver stack.
  uint32_t current_config_index_;

  AddCollectionHandler add_collection_handler_;
  RemoveCollectionHandler remove_collection_handler_;
  ShowBufferHandler show_buffer_handler_;
  MuteStateHandler mute_state_handler_;

  // TODO(?????) - Is this really the ideal way to communicate status back?
  CommandStatusHandler command_status_handler_;

  // Track the moving region of interest
  MovingWindow moving_window_;

  // stream_infos_ uses the same index as the corresponding stream index in configurations_.
  struct StreamInfo {
    fuchsia::camera3::StreamPtr stream;
    fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info;
    std::optional<uint32_t> add_collection_handler_returned_value;
    std::optional<uint32_t>
        source_highlight;  // Stream on which to highlight this stream's crop region.
    std::optional<fuchsia::math::RectF> highlight;
    fuchsia::sysmem::ImageFormat_2 image_format;
    zx::time last_received;  // Last timestamp this stream received a frame.
  };
  std::map<uint32_t, StreamInfo> stream_infos_;

  friend class CameraGymTest;
  friend class CameraGymStreamCyclerTest;
  FRIEND_TEST(CameraGymTest, PendingCollectionId);
  FRIEND_TEST(StreamCyclerTest, SimpleConfiguration_ManualMode_ConnectToStream);
  FRIEND_TEST(StreamCyclerTest, ComplexConfiguration_ManualMode_WatchCurrentConfigurationCallback);
  FRIEND_TEST(StreamCyclerTest, ComplexConfiguration_ManualMode_ExecuteSetConfigCommand_SameConfig);
  FRIEND_TEST(StreamCyclerTest,
              ComplexConfiguration_ManualMode_ExecuteSetConfigCommand_DifferentConfig);
  FRIEND_TEST(StreamCyclerTest, ComplexConfiguration_ManualMode_ExecuteAddStreamCommand);
  FRIEND_TEST(StreamCyclerTest, ComplexConfiguration_ManualMode_ExecuteSetCropCommand);
  FRIEND_TEST(StreamCyclerTest, CommandSuccessNotify);
};

}  // namespace camera

#endif  // SRC_CAMERA_BIN_CAMERA_GYM_STREAM_CYCLER_H_
