// 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::FrameInfo 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::Configuration> 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_
