// 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/camera2/cpp/fidl.h>
#include <fuchsia/camera2/hal/cpp/fidl.h>
#include <fuchsia/io/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/fzl/fdio.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/sys/cpp/component_context.h>

#include <initializer_list>
#include <memory>
#include <vector>

#include "gtest/gtest.h"
#include "src/lib/syslog/cpp/logger.h"

namespace {

constexpr uint32_t kBufferCountForCamping = 2;
constexpr uint32_t kFakeImageMinWidth = 10;
constexpr uint32_t kFakeImageMaxWidth = 0;  // Treated as max
constexpr uint32_t kFakeImageMinHeight = 10;
constexpr uint32_t kFakeImageMaxHeight = 0;  // Treated as max.
constexpr uint32_t kFakeImageMinBytesPerRow = 10;
constexpr uint32_t kFakeImageMaxBytesPerRow = 0;  // Treated as max.
constexpr uint32_t kFakeImageBytesPerRowDivisor = 128;
constexpr uint32_t kNumberOfLayers = 1;

fuchsia::sysmem::BufferCollectionConstraints GetFakeConstraints() {
  fuchsia::sysmem::BufferCollectionConstraints constraints;
  constraints.min_buffer_count_for_camping = kBufferCountForCamping;
  constraints.image_format_constraints_count = 1;
  auto& image_constraints = constraints.image_format_constraints[0];
  image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::NV12;
  image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::NV12;
  image_constraints.min_coded_width = kFakeImageMinWidth;
  image_constraints.max_coded_width = kFakeImageMaxWidth;
  image_constraints.min_coded_height = kFakeImageMinHeight;
  image_constraints.max_coded_height = kFakeImageMaxHeight;
  image_constraints.min_bytes_per_row = kFakeImageMinBytesPerRow;
  image_constraints.max_bytes_per_row = kFakeImageMaxBytesPerRow;
  image_constraints.layers = kNumberOfLayers;
  image_constraints.bytes_per_row_divisor = kFakeImageBytesPerRowDivisor;
  image_constraints.color_spaces_count = 1;
  image_constraints.color_space[0].type = fuchsia::sysmem::ColorSpaceType::REC601_PAL;
  constraints.usage.video = fuchsia::sysmem::videoUsageHwEncoder;
  return constraints;
}

class CameraManagerTest : public gtest::RealLoopFixture {
 public:
  CameraManagerTest() : context_(sys::ComponentContext::Create()) {}

  // testing::Test implementation.
  void SetUp() override {
    ASSERT_EQ(ZX_OK, context_->svc()->Connect(sysmem_allocator_.NewRequest()));
    ASSERT_EQ(ZX_OK, context_->svc()->Connect(camera_manager_.NewRequest()));
  }
  void TearDown() override {
    if (buffer_collection_.is_bound()) {
      buffer_collection_->Close();
    }
  }

  void GetToken(fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>* out_token) {
    // Create client_token which we'll hold on to to get our buffer_collection.
    fuchsia::sysmem::BufferCollectionTokenSyncPtr client_token;
    // Create camera_token to send to the camera manager
    fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> camera_token;
    // Start the allocation process
    ASSERT_EQ(ZX_OK, sysmem_allocator_->AllocateSharedCollection(client_token.NewRequest()));
    // Duplicate the token:
    client_token->Duplicate(std::numeric_limits<uint32_t>::max(), camera_token.NewRequest());
    ASSERT_EQ(ZX_OK, client_token->Sync());
    // Now convert our side into a Logical BufferCollection:
    sysmem_allocator_->BindSharedCollection(client_token.Unbind(), buffer_collection_.NewRequest());
    ASSERT_EQ(ZX_OK, buffer_collection_->SetConstraints(true, GetFakeConstraints()));
    *out_token = std::move(camera_token);
  }

 protected:
  fuchsia::sysmem::BufferCollectionSyncPtr buffer_collection_;
  std::unique_ptr<sys::ComponentContext> context_;
  fuchsia::camera2::ManagerSyncPtr camera_manager_;
  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator_;
};

TEST_F(CameraManagerTest, CanConnectToStream) {
  EXPECT_EQ(ZX_OK, camera_manager_->AcknowledgeDeviceEvent());

  fuchsia::camera2::StreamProperties stream_properties{};
  stream_properties.set_stream_type(fuchsia::camera2::CameraStreamType::MONITORING);
  fuchsia::camera2::StreamConstraints constraints{};
  constraints.set_properties(std::move(stream_properties));

  fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> token;
  fuchsia::camera2::StreamPtr stream;
  fuchsia::sysmem::ImageFormat_2 format;
  GetToken(&token);
  ASSERT_EQ(ZX_OK, camera_manager_->ConnectToStream(0, std::move(constraints), std::move(token),
                                                    stream.NewRequest(), &format));
  // Check that the other side of the stream channel has not been closed.  This is the
  // signal that the interface gives that ConnectToStream failed.
  ASSERT_EQ(ZX_ERR_TIMED_OUT,
            stream.channel().wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time::infinite_past(), nullptr))
      << "CameraManagerTest::CanConnectToStream: Failed to connect to stream";

  bool passed = false;
  bool stream_failure = false;
  stream.set_error_handler([&stream_failure](zx_status_t status) {
    stream_failure = true;
    FX_PLOGS(ERROR, status) << "Stream failed with error ";
  });
  stream.events().OnFrameAvailable = [&passed](fuchsia::camera2::FrameAvailableInfo frame) {
    passed = true;
  };
  stream->Start();
  RunLoopUntil([&passed, &stream_failure]() { return passed || stream_failure; });
  EXPECT_TRUE(passed);
}

}  // namespace
