// 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.

#include <fuchsia/hardware/camerahwaccel/c/banjo.h>
#include <lib/async/cpp/task.h>
#include <lib/fake_ddk/fake_ddk.h>
#include <lib/fit/result.h>
#include <lib/gtest/test_loop_fixture.h>
#include <lib/sys/cpp/component_context.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <utility>

#include <safemath/safe_conversions.h>

#include "src/camera/drivers/controller/controller_protocol.h"
#include "src/camera/drivers/controller/gdc_node.h"
#include "src/camera/drivers/controller/ge2d_node.h"
#include "src/camera/drivers/controller/graph_utils.h"
#include "src/camera/drivers/controller/input_node.h"
#include "src/camera/drivers/controller/isp_stream_protocol.h"
#include "src/camera/drivers/controller/output_node.h"
#include "src/camera/drivers/controller/pipeline_manager.h"
#include "src/camera/drivers/controller/sherlock/sherlock_product_config.h"
#include "src/camera/drivers/controller/test/constants.h"
#include "src/camera/drivers/controller/test/fake_gdc.h"
#include "src/camera/drivers/controller/test/fake_ge2d.h"
#include "src/camera/drivers/controller/test/fake_isp.h"

// NOTE: In this test, we are actually just unit testing the ControllerImpl class.
namespace camera {

namespace {

class ControllerProtocolTest : public gtest::TestLoopFixture {
 public:
  ControllerProtocolTest() : context_(sys::ComponentContext::CreateAndServeOutgoingDirectory()) {}

  void SetUp() override {
    ASSERT_EQ(ZX_OK, context_->svc()->Connect(sysmem_allocator1_.NewRequest()));
    ASSERT_EQ(ZX_OK, context_->svc()->Connect(sysmem_allocator2_.NewRequest()));
    ASSERT_EQ(ZX_OK, zx::event::create(0, &event_));

    isp_ = fake_isp_.client();
    gdc_ = fake_gdc_.client();
    ge2d_ = fake_ge2d_.client();
    pipeline_manager_ =
        std::make_unique<PipelineManager>(fake_ddk::kFakeParent, dispatcher(), isp_, gdc_, ge2d_,
                                          std::move(sysmem_allocator1_), event_);
    SherlockProductConfig sherlock_configs;
    internal_config_info_ = sherlock_configs.InternalConfigs();
  }

  void TearDown() override {
    pipeline_manager_ = nullptr;
    QuitLoop();
    context_ = nullptr;
    sysmem_allocator1_ = nullptr;
    sysmem_allocator2_ = nullptr;
  }

  InternalConfigNode* GetStreamConfigNode(uint32_t config_type,
                                          const fuchsia::camera2::CameraStreamType stream_type) {
    InternalConfigInfo& config_info = internal_config_info_.configs_info.at(0);

    if (config_type >= SherlockConfigs::MAX) {
      return nullptr;
    }

    config_info = internal_config_info_.configs_info.at(config_type);

    for (auto& stream_info : config_info.streams_info) {
      auto supported_streams = stream_info.supported_streams;
      if (std::any_of(supported_streams.begin(), supported_streams.end(),
                      [stream_type](auto& supported_stream) {
                        return supported_stream.type == stream_type;
                      })) {
        return &stream_info;
      }
    }
    return nullptr;
  }

  fuchsia::sysmem::BufferCollectionInfo_2 FakeBufferCollection() {
    fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection;
    buffer_collection.buffer_count = kNumBuffers;
    buffer_collection.settings.has_image_format_constraints = true;
    auto& constraints = buffer_collection.settings.image_format_constraints;
    constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::NV12;
    constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::NV12;
    constraints.max_coded_width = 4096;
    constraints.max_coded_height = 4096;
    constraints.max_bytes_per_row = 0xffffffff;
    return buffer_collection;
  }

  // This helper API does the basic validation of an Input Node.
  fit::result<std::unique_ptr<camera::InputNode>, zx_status_t> GetInputNode(
      const ControllerMemoryAllocator& allocator, StreamCreationData* info) {
    EXPECT_NE(nullptr, info);

    info->output_buffers = FakeBufferCollection();
    info->image_format_index = 0;

    auto result = camera::InputNode::CreateInputNode(info, allocator, dispatcher(), isp_);
    EXPECT_TRUE(result.is_ok());

    EXPECT_NE(nullptr, result.value()->isp_stream_protocol());
    EXPECT_EQ(NodeType::kInputStream, result.value()->type());
    return result;
  }

  // Returns |true| if all |streams| are present in the
  // vector |streams_to_validate|.
  bool HasAllStreams(const std::vector<fuchsia::camera2::CameraStreamType>& streams_to_validate,
                     const std::vector<fuchsia::camera2::CameraStreamType>& streams) const {
    if (streams_to_validate.size() != streams.size()) {
      return false;
    }
    for (auto stream : streams) {
      if (!camera::HasStreamType(streams_to_validate, stream)) {
        return false;
      }
    }
    return true;
  }

  zx_status_t SetupStream(uint32_t config, fuchsia::camera2::CameraStreamType stream_type,
                          fuchsia::camera2::StreamPtr& stream) {
    async::PostTask(dispatcher(), [this, config, stream_type, &stream]() {
      auto* stream_config_node = GetStreamConfigNode(config, stream_type);
      StreamCreationData info;
      fuchsia::camera2::hal::StreamConfig stream_config;
      stream_config.properties.set_stream_type(stream_type);
      info.stream_config = std::move(stream_config);
      info.node = *stream_config_node;
      info.output_buffers = FakeBufferCollection();
      info.image_format_index = 0;
      auto stream_request = stream.NewRequest();
      pipeline_manager_->ConfigureStreamPipeline(std::move(info), std::move(stream_request));
    });

    RunLoopUntilIdle();
    return ZX_OK;
  }

  std::vector<fuchsia::sysmem::ImageFormat_2> GetOutputFormats(
      const fuchsia::camera2::StreamPtr& stream) {
    bool callback_called = false;
    std::vector<fuchsia::sysmem::ImageFormat_2> output_formats;
    stream->GetImageFormats([&](std::vector<fuchsia::sysmem::ImageFormat_2> formats) {
      callback_called = true;
      output_formats = std::move(formats);
    });
    RunLoopUntilIdle();
    EXPECT_TRUE(callback_called);
    return output_formats;
  }

  rect_t GetRectFromCropParameters(float x_min, float y_min, float x_max, float y_max,
                                   uint32_t coded_width, uint32_t coded_height) {
    ZX_ASSERT(x_max >= x_min);
    ZX_ASSERT(y_max >= y_min);
    x_min = std::clamp(x_min, 0.0f, 1.0f);
    x_max = std::clamp(x_max, 0.0f, 1.0f);
    y_min = std::clamp(y_min, 0.0f, 1.0f);
    y_max = std::clamp(y_max, 0.0f, 1.0f);
    auto normalized_x_min =
        safemath::checked_cast<uint32_t>(x_min * safemath::checked_cast<float>(coded_width) + 0.5f);
    auto normalized_y_min = safemath::checked_cast<uint32_t>(
        y_min * safemath::checked_cast<float>(coded_height) + 0.5f);
    auto normalized_x_max =
        safemath::checked_cast<uint32_t>(x_max * safemath::checked_cast<float>(coded_width) + 0.5f);
    auto normalized_y_max = safemath::checked_cast<uint32_t>(
        y_max * safemath::checked_cast<float>(coded_height) + 0.5f);
    auto width = normalized_x_max - normalized_x_min;
    auto height = normalized_y_max - normalized_y_min;
    rect_t rect = {
        .x = normalized_x_min,
        .y = normalized_y_min,
        .width = width,
        .height = height,
    };
    return rect;
  }

  FakeIsp fake_isp_;
  FakeGdc fake_gdc_;
  FakeGe2d fake_ge2d_;
  zx::event event_;
  thrd_t controller_frame_processing_thread_;
  fuchsia::camera2::hal::ControllerSyncPtr camera_client_;
  std::unique_ptr<sys::ComponentContext> context_;
  std::unique_ptr<camera::PipelineManager> pipeline_manager_;
  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator1_;
  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator2_;
  ddk::IspProtocolClient isp_;
  ddk::GdcProtocolClient gdc_;
  ddk::Ge2dProtocolClient ge2d_;
  InternalConfigs internal_config_info_;
};

TEST_F(ControllerProtocolTest, TestConfigureMonitorConfigStreamFR) {
  fuchsia::camera2::StreamPtr stream;
  auto stream_type1 = kStreamTypeDS | kStreamTypeML;
  auto stream_type2 = kStreamTypeFR | kStreamTypeML;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type2, stream));

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* output_node = static_cast<OutputNode*>(fr_head_node->child_nodes().at(0).get());

  // Check if all nodes were created.
  EXPECT_EQ(NodeType::kInputStream, fr_head_node->type());
  EXPECT_EQ(NodeType::kOutputStream, output_node->type());

  // Validate the configured streams for all nodes.
  EXPECT_TRUE(HasAllStreams(fr_head_node->configured_streams(), {stream_type2}));
  EXPECT_TRUE(HasAllStreams(output_node->configured_streams(), {stream_type2}));

  EXPECT_TRUE(fr_head_node->is_stream_supported(stream_type1));
  EXPECT_TRUE(fr_head_node->is_stream_supported(stream_type2));

  // Check if client_stream is valid.
  EXPECT_NE(nullptr, output_node->client_stream());

  auto output_formats = GetOutputFormats(stream);
  EXPECT_EQ(output_formats.size(), 1u);
}

TEST_F(ControllerProtocolTest, TestConfigureMonitorConfigStreamDS) {
  auto stream_type1 = kStreamTypeDS | kStreamTypeML;
  auto stream_type2 = kStreamTypeFR | kStreamTypeML;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type1, stream));

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* gdc_node = static_cast<GdcNode*>(fr_head_node->child_nodes().at(0).get());
  auto* output_node = static_cast<OutputNode*>(gdc_node->child_nodes().at(0).get());

  // Check if all nodes were created.
  EXPECT_EQ(NodeType::kGdc, gdc_node->type());
  EXPECT_EQ(NodeType::kInputStream, fr_head_node->type());
  EXPECT_EQ(NodeType::kOutputStream, output_node->type());

  // Validate the configured streams for all nodes.
  EXPECT_TRUE(HasAllStreams(fr_head_node->configured_streams(), {stream_type1}));
  EXPECT_TRUE(HasAllStreams(gdc_node->configured_streams(), {stream_type1}));
  EXPECT_TRUE(HasAllStreams(output_node->configured_streams(), {stream_type1}));

  EXPECT_TRUE(fr_head_node->is_stream_supported(stream_type1));
  EXPECT_TRUE(fr_head_node->is_stream_supported(stream_type2));
  EXPECT_TRUE(gdc_node->is_stream_supported(stream_type1));
  EXPECT_TRUE(output_node->is_stream_supported(stream_type1));

  // Check if client_stream is valid.
  EXPECT_NE(nullptr, output_node->client_stream());

  auto output_formats = GetOutputFormats(stream);
  EXPECT_EQ(output_formats.size(), 1u);
}

TEST_F(ControllerProtocolTest, TestConfigureVideoConfigStream1) {
  auto stream_type = kStreamTypeFR | kStreamTypeML | kStreamTypeVideo;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::VIDEO, stream_type, stream));

  fuchsia::camera2::StreamPtr stream_video;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::VIDEO, kStreamTypeVideo, stream_video));

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* gdc1_node = static_cast<GdcNode*>(fr_head_node->child_nodes().at(0).get());
  auto* gdc2_node = static_cast<GdcNode*>(gdc1_node->child_nodes().at(0).get());
  auto* output_node = static_cast<OutputNode*>(gdc2_node->child_nodes().at(0).get());
  auto* ge2d_node = static_cast<Ge2dNode*>(gdc1_node->child_nodes().at(1).get());
  auto* output_node_video = static_cast<OutputNode*>(ge2d_node->child_nodes().at(0).get());

  // Check if all nodes were created appropriately.
  EXPECT_EQ(NodeType::kGdc, gdc1_node->type());
  EXPECT_EQ(NodeType::kGdc, gdc2_node->type());
  EXPECT_EQ(NodeType::kGe2d, ge2d_node->type());
  EXPECT_EQ(NodeType::kInputStream, fr_head_node->type());
  EXPECT_EQ(NodeType::kOutputStream, output_node->type());
  EXPECT_EQ(NodeType::kOutputStream, output_node_video->type());

  // Validate the configured streams for all nodes.
  EXPECT_TRUE(HasAllStreams(fr_head_node->configured_streams(), {stream_type, kStreamTypeVideo}));
  EXPECT_TRUE(HasAllStreams(gdc1_node->configured_streams(), {stream_type, kStreamTypeVideo}));
  EXPECT_TRUE(HasAllStreams(gdc2_node->configured_streams(), {stream_type}));
  EXPECT_TRUE(HasAllStreams(ge2d_node->configured_streams(), {kStreamTypeVideo}));
  EXPECT_TRUE(HasAllStreams(output_node->configured_streams(), {stream_type}));
  EXPECT_TRUE(HasAllStreams(output_node_video->configured_streams(), {kStreamTypeVideo}));

  EXPECT_TRUE(fr_head_node->is_stream_supported(stream_type));
  EXPECT_TRUE(fr_head_node->is_stream_supported(kStreamTypeVideo));
  EXPECT_TRUE(gdc1_node->is_stream_supported(stream_type));
  EXPECT_TRUE(gdc1_node->is_stream_supported(kStreamTypeVideo));
  EXPECT_TRUE(gdc2_node->is_stream_supported(stream_type));
  EXPECT_TRUE(ge2d_node->is_stream_supported(kStreamTypeVideo));
  EXPECT_TRUE(output_node->is_stream_supported(stream_type));
  EXPECT_TRUE(output_node_video->is_stream_supported(kStreamTypeVideo));

  // Check if client_stream is valid.
  EXPECT_NE(nullptr, output_node->client_stream());
  EXPECT_NE(nullptr, output_node_video->client_stream());

  auto output_formats = GetOutputFormats(stream);
  EXPECT_EQ(output_formats.size(), 1u);

  output_formats = GetOutputFormats(stream_video);
  ASSERT_EQ(output_formats.size(), 3u);
}

TEST_F(ControllerProtocolTest, TestHasStreamType) {
  std::vector<fuchsia::camera2::CameraStreamType> input_vector;
  auto stream_to_find = kStreamTypeFR;

  EXPECT_FALSE(HasStreamType(input_vector, stream_to_find));

  input_vector.push_back(kStreamTypeML);
  input_vector.push_back(kStreamTypeMonitoring);

  EXPECT_FALSE(HasStreamType(input_vector, stream_to_find));

  input_vector.push_back(kStreamTypeFR);
  EXPECT_TRUE(HasStreamType(input_vector, stream_to_find));
}

TEST_F(ControllerProtocolTest, TestNextNodeInPipeline) {
  auto* stream_config_node =
      GetStreamConfigNode(SherlockConfigs::MONITORING, kStreamTypeDS | kStreamTypeML);
  ASSERT_NE(nullptr, stream_config_node);

  StreamCreationData info;
  fuchsia::camera2::hal::StreamConfig stream_config;
  stream_config.properties.set_stream_type(kStreamTypeDS | kStreamTypeML);
  info.stream_config = std::move(stream_config);
  info.node = *stream_config_node;

  // Expecting 1st node to be input node.
  EXPECT_EQ(NodeType::kInputStream, stream_config_node->type);

  // Using ML|DS stream in Monitor configuration for test here.
  const auto* next_node = camera::GetNextNodeInPipeline(info.stream_config.properties.stream_type(),
                                                        *stream_config_node);
  ASSERT_NE(nullptr, next_node);

  // Expecting 2nd node to be input node.
  EXPECT_EQ(NodeType::kGdc, next_node->type);

  next_node =
      camera::GetNextNodeInPipeline(info.stream_config.properties.stream_type(), *next_node);
  ASSERT_NE(nullptr, next_node);

  // Expecting 3rd node to be input node.
  EXPECT_EQ(NodeType::kOutputStream, next_node->type);
}

TEST_F(ControllerProtocolTest, TestFrameErrors) {
  auto stream_type = kStreamTypeFR | kStreamTypeML;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type, stream));

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();

  // Invoke OnFrameAvailable() for the ISP node. Buffer index = 1.
  frame_available_info_t frame_info = {
      .frame_status = FRAME_STATUS_ERROR_BUFFER_FULL,
      .buffer_id = 1,
      .metadata =
          {
              .timestamp = static_cast<uint64_t>(zx_clock_get_monotonic()),
              .image_format_index = 0,
              .input_buffer_index = 0,
          },
  };

  // Provide a frame to  the ISP node. In this configuration the
  // first 3 frames will be dropped (released back to the ISP).
  EXPECT_NO_FATAL_FAILURE(fr_head_node->OnReadyToProcess(&frame_info));
  RunLoopUntilIdle();
  // Ensure that the frame is not released.
  EXPECT_FALSE(fake_isp_.frame_released());

  frame_info.frame_status = FRAME_STATUS_OK;
  EXPECT_NO_FATAL_FAILURE(fr_head_node->OnReadyToProcess(&frame_info));
  RunLoopUntilIdle();
  // Ensure that the frame is released.
  EXPECT_TRUE(fake_isp_.frame_released());
}

TEST_F(ControllerProtocolTest, TestMultipleStartStreaming) {
  auto stream_type = kStreamTypeFR | kStreamTypeML;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type, stream));

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* output_node = static_cast<OutputNode*>(fr_head_node->child_nodes().at(0).get());

  // Set streaming on.
  auto initial_start_count = fake_isp_.start_stream_counter();
  output_node->client_stream()->Start();
  auto updated_start_count = fake_isp_.start_stream_counter();
  EXPECT_EQ(updated_start_count, initial_start_count + 1);
  EXPECT_NO_FATAL_FAILURE(output_node->client_stream()->Start());
  // Check if the ISP StartStream() was invoked twice.
  EXPECT_EQ(fake_isp_.start_stream_counter(), updated_start_count + 1);
}

TEST_F(ControllerProtocolTest, TestMultipleStopStreaming) {
  auto stream_type = kStreamTypeFR | kStreamTypeML;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type, stream));

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* output_node = static_cast<OutputNode*>(fr_head_node->child_nodes().at(0).get());

  // Set streaming off.
  auto initial_stop_count = fake_isp_.stop_stream_counter();
  output_node->client_stream()->Stop();
  auto updated_stop_count = fake_isp_.stop_stream_counter();
  EXPECT_EQ(updated_stop_count, initial_stop_count + 1);
  EXPECT_NO_FATAL_FAILURE(output_node->client_stream()->Stop());
  EXPECT_EQ(fake_isp_.stop_stream_counter(), updated_stop_count + 1);
}

TEST_F(ControllerProtocolTest, TestMonitorMultiStreamFRBadOrder) {
  auto stream_type1 = kStreamTypeDS | kStreamTypeML;
  auto stream_type2 = kStreamTypeFR | kStreamTypeML;
  fuchsia::camera2::StreamPtr stream1;
  fuchsia::camera2::StreamPtr stream2;

  bool stream_alive = true;
  stream2.set_error_handler([&](zx_status_t /* status*/) { stream_alive = false; });

  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type1, stream1));
  EXPECT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type2, stream2));
  EXPECT_FALSE(stream_alive);
}

TEST_F(ControllerProtocolTest, TestMonitorMultiStreamFR) {
  fuchsia::camera2::StreamPtr stream1;
  fuchsia::camera2::StreamPtr stream2;

  auto stream_type1 = kStreamTypeDS | kStreamTypeML;
  auto stream_type2 = kStreamTypeFR | kStreamTypeML;

  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type2, stream2));
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type1, stream1));

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* fr_ml_output_node = static_cast<OutputNode*>(fr_head_node->child_nodes().at(0).get());
  auto* gdc_node = static_cast<GdcNode*>(fr_head_node->child_nodes().at(1).get());
  auto* ds_ml_output_node = static_cast<OutputNode*>(gdc_node->child_nodes().at(0).get());

  // Validate input node.
  EXPECT_TRUE(HasAllStreams(fr_head_node->configured_streams(), {stream_type1, stream_type2}));
  EXPECT_TRUE(fr_head_node->is_stream_supported(stream_type1));
  EXPECT_TRUE(fr_head_node->is_stream_supported(stream_type2));

  // Check if client_stream is valid.
  ASSERT_NE(nullptr, fr_ml_output_node->client_stream());
  ASSERT_NE(nullptr, ds_ml_output_node->client_stream());

  // Start streaming on FR|ML stream. Expecting other stream to be disabled.
  fr_ml_output_node->client_stream()->Start();
  EXPECT_TRUE(fr_head_node->enabled());
  EXPECT_TRUE(fr_ml_output_node->enabled());
  EXPECT_FALSE(gdc_node->enabled());
  EXPECT_FALSE(ds_ml_output_node->enabled());

  // Start streaming on DS|ML stream.
  ds_ml_output_node->client_stream()->Start();
  EXPECT_TRUE(fr_head_node->enabled());
  EXPECT_TRUE(fr_ml_output_node->enabled());
  EXPECT_TRUE(gdc_node->enabled());
  EXPECT_TRUE(ds_ml_output_node->enabled());

  // Stop streaming on FR|ML stream.
  fr_ml_output_node->client_stream()->Stop();
  EXPECT_TRUE(fr_head_node->enabled());
  EXPECT_FALSE(fr_ml_output_node->enabled());
  EXPECT_TRUE(gdc_node->enabled());
  EXPECT_TRUE(ds_ml_output_node->enabled());

  // Stop streaming on DS|ML stream.
  ds_ml_output_node->client_stream()->Stop();
  EXPECT_FALSE(fr_head_node->enabled());
  EXPECT_FALSE(fr_ml_output_node->enabled());
  EXPECT_FALSE(gdc_node->enabled());
  EXPECT_FALSE(ds_ml_output_node->enabled());

  auto output_formats = GetOutputFormats(stream1);
  EXPECT_EQ(output_formats.size(), 1u);

  output_formats = GetOutputFormats(stream2);
  EXPECT_EQ(output_formats.size(), 1u);
}

TEST_F(ControllerProtocolTest, TestInUseBufferCounts) {
  auto stream_type = kStreamTypeFR | kStreamTypeML;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type, stream));

  bool stream_alive = true;
  stream.set_error_handler([&](zx_status_t /*status*/) { stream_alive = false; });

  bool frame_received = false;
  stream.events().OnFrameAvailable = [&](fuchsia::camera2::FrameAvailableInfo info) {
    frame_received = true;
  };

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();

  // Start streaming.
  async::PostTask(dispatcher(), [&stream]() { stream->Start(); });
  RunLoopUntilIdle();

  // ISP is single parent for two nodes.
  // Invoke OnFrameAvailable() for the ISP node. Buffer index = 1.
  frame_available_info_t frame_info = {
      .frame_status = FRAME_STATUS_OK,
      .buffer_id = 1,
      .metadata =
          {
              .timestamp = static_cast<uint64_t>(zx_clock_get_monotonic()),
              .image_format_index = 0,
              .input_buffer_index = 0,
          },
  };

  for (uint32_t i = 0; i < kNumBuffers; i++) {
    frame_info.buffer_id = i;
    async::PostTask(dispatcher(),
                    [&fr_head_node, frame_info] { fr_head_node->OnReadyToProcess(&frame_info); });
    RunLoopUntilIdle();
  }

  while (!frame_received) {
    RunLoopUntilIdle();
  }

  EXPECT_TRUE(frame_received);
  EXPECT_EQ(fr_head_node->get_in_use_buffer_count(0), 0u);
  EXPECT_EQ(fr_head_node->get_in_use_buffer_count(1), 0u);
  EXPECT_EQ(fr_head_node->get_in_use_buffer_count(2), 1u);
  EXPECT_EQ(fr_head_node->get_in_use_buffer_count(3), 0u);

  async::PostTask(dispatcher(), [&stream]() { stream->ReleaseFrame(2); });
  RunLoopUntilIdle();

  EXPECT_EQ(fr_head_node->get_in_use_buffer_count(2), 0u);

  stream->Stop();
}

TEST_F(ControllerProtocolTest, TestOutputNode) {
  auto stream_type = kStreamTypeDS | kStreamTypeML;
  auto* stream_config_node = GetStreamConfigNode(SherlockConfigs::MONITORING, stream_type);
  ASSERT_NE(nullptr, stream_config_node);
  StreamCreationData info;
  fuchsia::camera2::hal::StreamConfig stream_config;
  stream_config.properties.set_stream_type(stream_type);
  info.stream_config = std::move(stream_config);
  info.node = *stream_config_node;

  ControllerMemoryAllocator allocator(std::move(sysmem_allocator2_));

  // Testing successful creation of |OutputNode|.
  auto input_result = GetInputNode(allocator, &info);
  auto output_result =
      OutputNode::CreateOutputNode(dispatcher(), &info, input_result.value().get(), info.node);
  EXPECT_TRUE(output_result.is_ok());
  ASSERT_NE(nullptr, output_result.value());
  EXPECT_NE(nullptr, output_result.value()->client_stream());
  EXPECT_EQ(NodeType::kOutputStream, output_result.value()->type());

  // Passing invalid arguments.
  output_result =
      OutputNode::CreateOutputNode(nullptr, &info, input_result.value().get(), info.node);
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, output_result.error());

  output_result =
      OutputNode::CreateOutputNode(dispatcher(), nullptr, input_result.value().get(), info.node);
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, output_result.error());

  output_result = OutputNode::CreateOutputNode(dispatcher(), &info, nullptr, info.node);
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, output_result.error());
}

TEST_F(ControllerProtocolTest, TestGdcNode) {
  auto* stream_config_node =
      GetStreamConfigNode(SherlockConfigs::MONITORING, kStreamTypeDS | kStreamTypeML);
  ASSERT_NE(nullptr, stream_config_node);
  StreamCreationData info;
  fuchsia::camera2::hal::StreamConfig stream_config;
  stream_config.properties.set_stream_type(kStreamTypeDS | kStreamTypeML);
  info.stream_config = std::move(stream_config);
  info.node = *stream_config_node;
  ControllerMemoryAllocator allocator(std::move(sysmem_allocator2_));

  auto input_result = GetInputNode(allocator, &info);
  // Testing successful creation of |GdcNode|.
  auto* next_node_internal = GetNextNodeInPipeline(kStreamTypeDS | kStreamTypeML, info.node);
  ASSERT_NE(nullptr, next_node_internal);
  auto gdc_result = GdcNode::CreateGdcNode(allocator, dispatcher(), fake_ddk::kFakeParent, gdc_,
                                           &info, input_result.value().get(), *next_node_internal);
  EXPECT_TRUE(gdc_result.is_ok());
  ASSERT_NE(nullptr, gdc_result.value());
  EXPECT_EQ(NodeType::kGdc, gdc_result.value()->type());
}

TEST_F(ControllerProtocolTest, TestReleaseAfterStopStreaming) {
  auto stream_type = kStreamTypeDS | kStreamTypeML;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type, stream));

  // Start streaming.
  async::PostTask(dispatcher(), [&stream]() { stream->Start(); });
  RunLoopUntilIdle();

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* gdc_node = static_cast<GdcNode*>(fr_head_node->child_nodes().at(0).get());
  auto* ds_ml_output_node = static_cast<OutputNode*>(gdc_node->child_nodes().at(0).get());

  EXPECT_FALSE(fake_isp_.frame_released());

  EXPECT_TRUE(fr_head_node->enabled());
  EXPECT_TRUE(gdc_node->enabled());
  EXPECT_TRUE(ds_ml_output_node->enabled());

  // Stop streaming.
  async::PostTask(dispatcher(), [&stream]() { stream->Stop(); });
  RunLoopUntilIdle();

  EXPECT_FALSE(fr_head_node->enabled());
  EXPECT_FALSE(gdc_node->enabled());
  EXPECT_FALSE(ds_ml_output_node->enabled());

  // Invoke OnFrameAvailable() for the ISP node. Buffer index = 1.
  frame_available_info_t frame_info = {
      .frame_status = FRAME_STATUS_OK,
      .buffer_id = 1,
      .metadata =
          {
              .timestamp = static_cast<uint64_t>(zx_clock_get_monotonic()),
              .image_format_index = 0,
              .input_buffer_index = 0,
          },
  };

  // Making a frame available to ISP node.
  // Expecting the frame to be released since node is disabled.
  EXPECT_NO_FATAL_FAILURE(fr_head_node->OnReadyToProcess(&frame_info));
  RunLoopUntilIdle();
  EXPECT_TRUE(fake_isp_.frame_released());

  // Making a frame available to GDC node.
  // Expecting the frame to be released since node is disabled.
  EXPECT_NO_FATAL_FAILURE(gdc_node->OnFrameAvailable(&frame_info));
  RunLoopUntilIdle();
  EXPECT_TRUE(fake_gdc_.frame_released());
}

TEST_F(ControllerProtocolTest, TestEnabledDisableStreaming) {
  fuchsia::camera2::StreamPtr stream_ds;
  fuchsia::camera2::StreamPtr stream_fr;

  auto stream_type_ds = kStreamTypeDS | kStreamTypeML;
  auto stream_type_fr = kStreamTypeFR | kStreamTypeML;

  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type_fr, stream_fr));
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type_ds, stream_ds));

  // Start streaming.
  async::PostTask(dispatcher(), [&stream_fr]() { stream_fr->Start(); });
  async::PostTask(dispatcher(), [&stream_ds]() { stream_ds->Start(); });
  RunLoopUntilIdle();

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* fr_ml_output_node = static_cast<OutputNode*>(fr_head_node->child_nodes().at(0).get());
  auto* gdc_node = static_cast<GdcNode*>(fr_head_node->child_nodes().at(1).get());
  auto* ds_ml_output_node = static_cast<OutputNode*>(gdc_node->child_nodes().at(0).get());

  EXPECT_TRUE(fr_head_node->enabled());
  EXPECT_TRUE(fr_ml_output_node->enabled());
  EXPECT_TRUE(gdc_node->enabled());
  EXPECT_TRUE(ds_ml_output_node->enabled());

  async::PostTask(dispatcher(), [this]() { pipeline_manager_->StopStreaming(); });
  RunLoopUntilIdle();

  EXPECT_FALSE(fr_head_node->enabled());
  EXPECT_FALSE(fr_ml_output_node->enabled());
  EXPECT_FALSE(gdc_node->enabled());
  EXPECT_FALSE(ds_ml_output_node->enabled());

  async::PostTask(dispatcher(), [this]() { pipeline_manager_->StartStreaming(); });
  RunLoopUntilIdle();

  EXPECT_TRUE(fr_head_node->enabled());
  EXPECT_TRUE(fr_ml_output_node->enabled());
  EXPECT_TRUE(gdc_node->enabled());
  EXPECT_TRUE(ds_ml_output_node->enabled());
}

constexpr uint64_t FakeCaptureTimestamp(uint32_t id) { return 10000 * (id + 1); }
constexpr uint64_t FakeTimestamp(uint32_t id) { return FakeCaptureTimestamp(id) + 1000; }

TEST_F(ControllerProtocolTest, TestMultipleFrameRates) {
  auto fr_stream_type = kStreamTypeFR | kStreamTypeML;
  auto ds_stream_type = kStreamTypeMonitoring;
  fuchsia::camera2::StreamPtr fr_stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, fr_stream_type, fr_stream));

  fuchsia::camera2::StreamPtr ds_stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, ds_stream_type, ds_stream));

  bool fr_stream_alive = true;
  fr_stream.set_error_handler([&](zx_status_t /*status*/) { fr_stream_alive = false; });

  bool fr_frame_received = false;
  uint32_t fr_frame_index = 0;
  fr_stream.events().OnFrameAvailable = [&](fuchsia::camera2::FrameAvailableInfo info) {
    fr_frame_received = true;
    fr_frame_index = info.buffer_id;
    // FR node should use timestamp as capture time.
    EXPECT_EQ(info.metadata.capture_timestamp(), info.metadata.timestamp());
    // FR should use the timestamp reported by the driver.
    EXPECT_EQ(info.metadata.timestamp(), static_cast<int64_t>(FakeTimestamp(info.buffer_id)));
  };

  bool ds_stream_alive = true;
  ds_stream.set_error_handler([&](zx_status_t /*status*/) { ds_stream_alive = false; });

  bool ds_frame_received = false;
  uint32_t ds_frame_index = 0;
  uint32_t ds_frame_count = 0;
  ds_stream.events().OnFrameAvailable = [&](fuchsia::camera2::FrameAvailableInfo info) {
    ds_frame_received = true;
    ds_frame_index = info.buffer_id;
    ds_frame_count++;
    // DS should have the same capture timestamp as FR.
    EXPECT_EQ(info.metadata.capture_timestamp(),
              static_cast<int64_t>(FakeTimestamp(info.buffer_id)));
    // The fake GE2D driver adds a delay in its timestamp reporting.
    EXPECT_EQ(info.metadata.timestamp(),
              info.metadata.capture_timestamp() + FakeGe2d::kFrameDelayClocks);
  };

  auto* fr_head_node = pipeline_manager_->full_resolution_stream();
  auto* ds_head_node = pipeline_manager_->downscaled_resolution_stream();

  // Start streaming.
  async::PostTask(dispatcher(), [&fr_stream]() { fr_stream->Start(); });
  async::PostTask(dispatcher(), [&ds_stream]() { ds_stream->Start(); });
  RunLoopUntilIdle();

  // Invoke OnFrameAvailable() for the ISP node. Buffer index = 1.
  for (uint32_t i = 0; i < kNumBuffers; i++) {
    async::PostTask(dispatcher(), [i, &fr_head_node]() {
      frame_available_info_t info{
          .frame_status = FRAME_STATUS_OK,
          .buffer_id = i,
          .metadata{.timestamp = FakeTimestamp(i), .capture_timestamp = FakeCaptureTimestamp(i)}};
      fr_head_node->OnReadyToProcess(&info);
    });
    RunLoopUntilIdle();
    async::PostTask(dispatcher(), [i, &ds_head_node]() {
      frame_available_info_t info{
          .frame_status = FRAME_STATUS_OK,
          .buffer_id = i,
          .metadata{.timestamp = FakeTimestamp(i), .capture_timestamp = FakeCaptureTimestamp(i)}};
      ds_head_node->OnReadyToProcess(&info);
    });
    RunLoopUntilIdle();
  }

  EXPECT_EQ(fr_frame_index, 2u);
  EXPECT_EQ(ds_frame_index, 4u);
  EXPECT_EQ(ds_frame_count, 5u);
}

TEST_F(ControllerProtocolTest, TestFindGraphHead) {
  auto fr_stream_type = kStreamTypeFR | kStreamTypeML;
  auto ds_stream_type = kStreamTypeMonitoring;
  fuchsia::camera2::StreamPtr fr_stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, fr_stream_type, fr_stream));

  fuchsia::camera2::StreamPtr ds_stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, ds_stream_type, ds_stream));

  auto result = pipeline_manager_->FindGraphHead(fr_stream_type);
  EXPECT_FALSE(result.is_error());
  EXPECT_EQ(fuchsia::camera2::CameraStreamType::FULL_RESOLUTION, result.value().second);

  result = pipeline_manager_->FindGraphHead(ds_stream_type);
  EXPECT_FALSE(result.is_error());
  EXPECT_EQ(fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION, result.value().second);

  result = pipeline_manager_->FindGraphHead(kStreamTypeVideo);
  EXPECT_TRUE(result.is_error());
  EXPECT_EQ(result.error(), ZX_ERR_BAD_STATE);
}

TEST_F(ControllerProtocolTest, TestResolutionChange) {
  auto ds_stream_type = kStreamTypeMonitoring;
  fuchsia::camera2::StreamPtr ds_stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, ds_stream_type, ds_stream));

  auto* ds_head_node = pipeline_manager_->downscaled_resolution_stream();
  auto* gdc_node = static_cast<GdcNode*>(ds_head_node->child_nodes().at(0).get());
  auto* ge2d_node = static_cast<GdcNode*>(gdc_node->child_nodes().at(0).get());
  auto* output_node = static_cast<GdcNode*>(ge2d_node->child_nodes().at(0).get());

  bool ds_stream_alive = true;
  ds_stream.set_error_handler([&](zx_status_t /*status*/) { ds_stream_alive = false; });

  uint32_t old_resolution = 0;
  uint32_t new_resolution = 1;
  uint32_t ds_frame_count = 0;
  ds_stream.events().OnFrameAvailable = [&](fuchsia::camera2::FrameAvailableInfo info) {
    ds_frame_count++;
    if (ds_frame_count > 1) {
      EXPECT_EQ(gdc_node->current_image_format_index(), new_resolution);
      EXPECT_EQ(ge2d_node->current_image_format_index(), new_resolution);
      EXPECT_EQ(output_node->current_image_format_index(), new_resolution);
      EXPECT_EQ(new_resolution, info.metadata.image_format_index());
    } else {
      EXPECT_EQ(gdc_node->current_image_format_index(), old_resolution);
      EXPECT_EQ(ge2d_node->current_image_format_index(), old_resolution);
      EXPECT_EQ(output_node->current_image_format_index(), old_resolution);
      EXPECT_EQ(old_resolution, info.metadata.image_format_index());
    }
  };

  EXPECT_EQ(gdc_node->type(), NodeType::kGdc);

  // Start streaming.
  async::PostTask(dispatcher(), [&ds_stream]() { ds_stream->Start(); });
  RunLoopUntilIdle();

  // Invoke OnFrameAvailable() for the ISP node.
  frame_available_info_t frame_info = {
      .frame_status = FRAME_STATUS_OK,
      .buffer_id = 0,
      .metadata =
          {
              .timestamp = static_cast<uint64_t>(zx_clock_get_monotonic()),
              .image_format_index = old_resolution,
              .input_buffer_index = 0,
          },
  };
  // Post 1 frame with old resolution.
  async::PostTask(dispatcher(),
                  [&frame_info, &ds_head_node]() { ds_head_node->OnReadyToProcess(&frame_info); });
  RunLoopUntilIdle();

  auto callback_called = false;
  async::PostTask(dispatcher(), [&]() {
    ds_stream->SetImageFormat(10u, [&](zx_status_t status) {
      callback_called = true;
      EXPECT_EQ(status, ZX_ERR_INVALID_ARGS);
    });
  });
  RunLoopUntilIdle();
  ASSERT_EQ(callback_called, true);

  callback_called = false;
  async::PostTask(dispatcher(), [&]() {
    ds_stream->SetImageFormat(new_resolution, [&](zx_status_t status) {
      callback_called = true;
      EXPECT_EQ(status, ZX_OK);
    });
  });
  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);

  // Post other frames.
  for (uint32_t i = 1; i < kNumBuffers; i++) {
    async::PostTask(dispatcher(), [&frame_info, &ds_head_node, i]() {
      frame_info.buffer_id = i;
      ds_head_node->OnReadyToProcess(&frame_info);
    });
    RunLoopUntilIdle();
  }
  EXPECT_EQ(ds_frame_count, static_cast<uint32_t>(kNumBuffers));
}

TEST_F(ControllerProtocolTest, TestPipelineManagerShutdown) {
  fuchsia::camera2::StreamPtr stream_ds;
  fuchsia::camera2::StreamPtr stream_fr;

  auto stream_type_ds = kStreamTypeDS | kStreamTypeML;
  auto stream_type_fr = kStreamTypeFR | kStreamTypeML;

  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type_fr, stream_fr));
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type_ds, stream_ds));

  // Start streaming.
  async::PostTask(dispatcher(), [&stream_fr]() { stream_fr->Start(); });
  async::PostTask(dispatcher(), [&stream_ds]() { stream_ds->Start(); });
  RunLoopUntilIdle();

  async::PostTask(dispatcher(), [this]() { pipeline_manager_->Shutdown(); });
  RunLoopUntilIdle();

  zx_signals_t pending;
  event_.wait_one(kPipelineManagerSignalExitDone, zx::time::infinite(), &pending);

  EXPECT_EQ(nullptr, pipeline_manager_->full_resolution_stream());
  EXPECT_EQ(nullptr, pipeline_manager_->downscaled_resolution_stream());
}

TEST_F(ControllerProtocolTest, TestStreamShutdownAfterPipelineShutdown) {
  fuchsia::camera2::StreamPtr stream_ds;
  fuchsia::camera2::StreamPtr stream_fr;

  auto stream_type_ds = kStreamTypeDS | kStreamTypeML;
  auto stream_type_fr = kStreamTypeFR | kStreamTypeML;

  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type_fr, stream_fr));
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type_ds, stream_ds));

  // Start streaming.
  async::PostTask(dispatcher(), [&stream_fr]() { stream_fr->Start(); });
  async::PostTask(dispatcher(), [&stream_ds]() { stream_ds->Start(); });
  RunLoopUntilIdle();

  async::PostTask(dispatcher(), [this]() { pipeline_manager_->Shutdown(); });
  async::PostTask(dispatcher(), [&stream_fr]() { stream_fr.Unbind(); });
  RunLoopUntilIdle();

  zx_signals_t pending;
  event_.wait_one(kPipelineManagerSignalExitDone, zx::time::infinite(), &pending);

  EXPECT_EQ(nullptr, pipeline_manager_->full_resolution_stream());
  EXPECT_EQ(nullptr, pipeline_manager_->downscaled_resolution_stream());
}

TEST_F(ControllerProtocolTest, TestCropRectChange) {
  auto stream_type = kStreamTypeVideo;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::VIDEO, stream_type, stream));

  // Start streaming.
  async::PostTask(dispatcher(), [&stream]() { stream->Start(); });
  RunLoopUntilIdle();

  fake_ge2d_.crop_rect().reset();
  auto callback_called = false;
  async::PostTask(dispatcher(), [&]() {
    stream->SetRegionOfInterest(0.0, 0.0, 0.0, 0.0, [&](zx_status_t status) {
      callback_called = true;
      EXPECT_EQ(status, ZX_OK);
    });
  });
  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);
  EXPECT_TRUE(fake_ge2d_.crop_rect().has_value());  // Was set_crop_rect() ever called?
  rect_t expected_rect_1 = GetRectFromCropParameters(0.0, 0.0, 0.0, 0.0, 2240, 1792);
  EXPECT_EQ(fake_ge2d_.crop_rect()->x, expected_rect_1.x);
  EXPECT_EQ(fake_ge2d_.crop_rect()->y, expected_rect_1.y);
  EXPECT_EQ(fake_ge2d_.crop_rect()->width, expected_rect_1.width);
  EXPECT_EQ(fake_ge2d_.crop_rect()->height, expected_rect_1.height);

  // x_min > x_max
  fake_ge2d_.crop_rect().reset();
  callback_called = false;
  async::PostTask(dispatcher(), [&]() {
    stream->SetRegionOfInterest(0.6, 0.0, 0.5, 0.0, [&](zx_status_t status) {
      callback_called = true;
      EXPECT_EQ(status, ZX_ERR_INVALID_ARGS);
    });
  });
  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);
  EXPECT_FALSE(fake_ge2d_.crop_rect().has_value());  // Was set_crop_rect() ever called?

  // y_min > y_max
  fake_ge2d_.crop_rect().reset();
  callback_called = false;
  async::PostTask(dispatcher(), [&]() {
    stream->SetRegionOfInterest(0.6, 0.0, 0.5, 0.0, [&](zx_status_t status) {
      callback_called = true;
      EXPECT_EQ(status, ZX_ERR_INVALID_ARGS);
    });
  });
  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);
  EXPECT_FALSE(fake_ge2d_.crop_rect().has_value());  // Was set_crop_rect() ever called?
}

TEST_F(ControllerProtocolTest, TestCropRectWithoutStart) {
  auto stream_type = kStreamTypeVideo;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::VIDEO, stream_type, stream));

  fake_ge2d_.crop_rect().reset();
  auto callback_called = false;
  async::PostTask(dispatcher(), [&]() {
    stream->SetRegionOfInterest(0.2, 0.4, 0.6, 0.8, [&](zx_status_t status) {
      callback_called = true;
      EXPECT_EQ(status, ZX_OK);
    });
  });
  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);
  EXPECT_TRUE(fake_ge2d_.crop_rect().has_value());  // Was set_crop_rect() ever called?
  rect_t expected_rect = GetRectFromCropParameters(0.2, 0.4, 0.6, 0.8, 2240, 1792);
  EXPECT_EQ(fake_ge2d_.crop_rect()->x, expected_rect.x);
  EXPECT_EQ(fake_ge2d_.crop_rect()->y, expected_rect.y);
  EXPECT_EQ(fake_ge2d_.crop_rect()->width, expected_rect.width);
  EXPECT_EQ(fake_ge2d_.crop_rect()->height, expected_rect.height);
}

TEST_F(ControllerProtocolTest, TestCropRectChangeInvalidStream) {
  auto stream_type = kStreamTypeMonitoring;
  fuchsia::camera2::StreamPtr stream;
  ASSERT_EQ(ZX_OK, SetupStream(SherlockConfigs::MONITORING, stream_type, stream));

  // Start streaming.
  async::PostTask(dispatcher(), [&stream]() { stream->Start(); });
  RunLoopUntilIdle();

  fake_ge2d_.crop_rect().reset();
  auto callback_called = false;
  async::PostTask(dispatcher(), [&]() {
    stream->SetRegionOfInterest(0.0, 0.0, 0.0, 0.0, [&](zx_status_t status) {
      callback_called = true;
      EXPECT_EQ(status, ZX_ERR_NOT_SUPPORTED);
    });
  });
  RunLoopUntilIdle();
  EXPECT_TRUE(callback_called);
  EXPECT_FALSE(fake_ge2d_.crop_rect().has_value());  // Was set_crop_rect() ever called?
}

TEST_F(ControllerProtocolTest, LoadGdcConfig) {
#ifdef INTERNAL_ACCESS
  auto config = ProductConfig::Create();
  auto result = camera::LoadGdcConfiguration(fake_ddk::kFakeParent, *config, GdcConfig::INVALID);
  EXPECT_TRUE(result.is_error());

  result = camera::LoadGdcConfiguration(fake_ddk::kFakeParent, *config, GdcConfig::MONITORING_360p);
  EXPECT_FALSE(result.is_error());
#else
  GTEST_SKIP();
#endif
}
}  // namespace

}  // namespace camera
