// Copyright 2019 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_DRIVERS_CONTROLLER_INPUT_NODE_H_
#define SRC_CAMERA_DRIVERS_CONTROLLER_INPUT_NODE_H_

#include <fuchsia/camera2/cpp/fidl.h>
#include <fuchsia/hardware/isp/cpp/banjo.h>
#include <lib/trace/event.h>
#include <zircon/assert.h>

#include "src/camera/drivers/controller/isp_stream_protocol.h"
#include "src/camera/drivers/controller/memory_allocation.h"
#include "src/camera/drivers/controller/processing_node.h"
#include "src/camera/drivers/controller/stream_pipeline_info.h"

// |InputNode| represents a |ProcessNode| which would talk to the
// ISP driver.
namespace camera {

class InputNode : public ProcessNode {
 public:
  InputNode(StreamCreationData* info,
            fuchsia::sysmem::BufferCollectionInfo_2 output_buffer_collection,
            async_dispatcher_t* dispatcher, const ddk::IspProtocolClient& isp)
      : ProcessNode(NodeType::kInputStream, nullptr, info->stream_type(), info->node.image_formats,
                    std::move(output_buffer_collection), info->node.supported_streams, dispatcher,
                    info->node.output_frame_rate, info->image_format_index),
        isp_stream_type_(info->node.input_stream_type),
        isp_frame_callback_{OnIspFrameAvailable, this},
        isp_(isp) {}

  // Creates an |InputNode| object.
  // 1. Creates the ISP stream protocol
  // 2. Creates the requested ISP stream
  // 3. Allocates buffers if needed
  // Args:
  // |info| : StreamCreationData for the requested stream.
  // |memory_allocator| : Memory allocator object to allocate memory using sysmem.
  // |dispatcher| : Dispatcher on which GDC tasks can be queued up.
  // |isp| : ISP protocol to talk to the driver.
  static fit::result<std::unique_ptr<InputNode>, zx_status_t> CreateInputNode(
      StreamCreationData* info, const ControllerMemoryAllocator& memory_allocator,
      async_dispatcher_t* dispatcher, const ddk::IspProtocolClient& isp);

  const hw_accel_frame_callback_t* isp_frame_callback() { return &isp_frame_callback_; }

  std::unique_ptr<camera::IspStreamProtocol>& isp_stream_protocol() { return isp_stream_protocol_; }

  void set_isp_stream_protocol(std::unique_ptr<camera::IspStreamProtocol> isp_stream_protocol) {
    isp_stream_protocol_ = std::move(isp_stream_protocol);
  }

  // Notifies that a frame is ready to be sent to the client.
  void OnReadyToProcess(const frame_available_info_t* info) override;

  // Releases the frame associated with | buffer_index |.
  void OnReleaseFrame(uint32_t buffer_index) override;

  // Notifies that a frame is done processing by this node.
  void OnFrameAvailable(const frame_available_info_t* info) override;

  // Shuts down the stream with ISP.
  void OnShutdown(fit::function<void(void)> shutdown_callback) override;

  // Notifies that the client has requested to start streaming.
  void OnStartStreaming() override;

  // Notifies that the client has requested to stop streaming.
  void OnStopStreaming() override;

  // Notifies that the client has requested to change resolution.
  void OnResolutionChangeRequest(uint32_t output_format_index) override {}

 private:
  // Notifies when a new frame is available from the ISP.
  static void OnIspFrameAvailable(void* ctx, const frame_available_info_t* info) {
    auto nonce = TRACE_NONCE();
    TRACE_DURATION("camera", "OnIspFrameAvailable");
    TRACE_FLOW_BEGIN("camera", "post_ready_to_process", nonce);
    // This method is invoked by the ISP in its own thread,
    // so the event must be marshalled to the
    // controller's thread.
    auto* input_node = static_cast<InputNode*>(ctx);
    input_node->RunOnMainThread([input_node, nonce, info = *info]() {
      TRACE_DURATION("camera", "OnIspFrameAvailable.task");
      TRACE_FLOW_END("camera", "post_ready_to_process", nonce);
      input_node->OnReadyToProcess(&info);
    });
  }

  // ISP stream type.
  __UNUSED fuchsia::camera2::CameraStreamType isp_stream_type_;
  // ISP Frame callback.
  hw_accel_frame_callback_t isp_frame_callback_;
  // ISP stream protocol.
  std::unique_ptr<IspStreamProtocol> isp_stream_protocol_;
  // Protocol to talk to ISP driver.
  ddk::IspProtocolClient isp_;
};

}  // namespace camera

#endif  // SRC_CAMERA_DRIVERS_CONTROLLER_INPUT_NODE_H_
