// 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/camera/cpp/fidl.h>
#include <lib/fake_ddk/fake_ddk.h>
#include <lib/gtest/test_loop_fixture.h>

#include <ddktl/protocol/sysmem.h>

#include "src/camera/drivers/controller/controller_device.h"
#include "src/camera/drivers/controller/controller_protocol.h"
#include "src/camera/drivers/controller/test/constants.h"
#include "src/camera/drivers/controller/test/fake_sysmem.h"

namespace camera {
namespace {

class ControllerDeviceTest : public gtest::TestLoopFixture {
 public:
  void SetUp() override {
    ddk_ = std::make_unique<fake_ddk::Bind>();
    static constexpr const uint32_t kNumSubDevices = 1;
    fbl::Array<fake_ddk::ProtocolEntry> protocols(new fake_ddk::ProtocolEntry[kNumSubDevices],
                                                  kNumSubDevices);
    protocols[0] = fake_sysmem_.ProtocolEntry();
    ddk_->SetProtocols(std::move(protocols));
    zx::event event;
    ASSERT_EQ(ZX_OK, zx::event::create(0, &event));

    composite_protocol_ops_t ops = {
        .get_fragment = [](void* ctx, const char* name, zx_device_t** out) -> bool {
          *out = fake_ddk::kFakeParent;
          return true;
        }};
    composite_protocol_t proto{&ops, &ops};

    ddk::CompositeProtocolClient composite(&proto);
    controller_device_ =
        std::make_unique<ControllerDevice>(fake_ddk::kFakeParent, composite, std::move(event));
  }

  void TearDown() override {
    if (controller_device_) {
      controller_device_->DdkAsyncRemove();
    }
    ASSERT_EQ(ddk_->WaitUntilRemove(), ZX_OK);
    ASSERT_TRUE(ddk_->Ok());
    ddk_ = nullptr;

    controller_protocol_ = nullptr;
    controller_device_ = nullptr;
  }

  static void FailErrorHandler(zx_status_t status) {
    ADD_FAILURE() << "Channel Failure: " << status;
  }

  static void WaitForChannelClosure(const zx::channel& channel) {
    // TODO(fxbug.dev/38554): allow unidirectional message processing
    // Currently, running a loop associated with fidl::InterfacePtr handles both inbound and
    // outbound messages. Depending on how quickly the server handles such requests, the
    // channel may or may not be closed by the time a single call to RunUntilIdle returns.
    zx_status_t status = channel.wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time::infinite(), nullptr);
    if (status != ZX_OK) {
      EXPECT_EQ(status, ZX_ERR_BAD_HANDLE);
    }
  }

  template <class T>
  void WaitForInterfaceClosure(fidl::InterfacePtr<T>& ptr, zx_status_t expected_epitaph) {
    bool epitaph_received = false;
    zx_status_t epitaph_status = ZX_OK;
    ptr.set_error_handler([&](zx_status_t status) {
      ASSERT_FALSE(epitaph_received) << "We should only get one epitaph!";
      epitaph_received = true;
      epitaph_status = status;
    });
    WaitForChannelClosure(ptr.channel());
    RunLoopUntilIdle();
    if (epitaph_received) {  // Epitaphs are not guaranteed to be returned.
      EXPECT_EQ(epitaph_status, expected_epitaph);
    }
  }

  void BindControllerProtocol() {
    ASSERT_EQ(controller_device_->DdkAdd("test-camera-controller"), ZX_OK);
    ASSERT_EQ(controller_device_->StartThread(), ZX_OK);
    ASSERT_EQ(camera_protocol_.Bind(std::move(ddk_->FidlClient())), ZX_OK);
    camera_protocol_.set_error_handler(FailErrorHandler);
    camera_protocol_->GetChannel2(controller_protocol_.NewRequest().TakeChannel());
    controller_protocol_.set_error_handler(FailErrorHandler);
    RunLoopUntilIdle();
  }

  std::unique_ptr<fake_ddk::Bind> ddk_;
  std::unique_ptr<ControllerDevice> controller_device_;
  fuchsia::hardware::camera::DevicePtr camera_protocol_;
  fuchsia::camera2::hal::ControllerPtr controller_protocol_;
  FakeSysmem fake_sysmem_;
};

// Verifies controller can start up and shut down.
TEST_F(ControllerDeviceTest, DdkLifecycle) {
  EXPECT_EQ(controller_device_->DdkAdd("test-camera-controller"), ZX_OK);
  EXPECT_EQ(controller_device_->StartThread(), ZX_OK);
  controller_device_->DdkAsyncRemove();
  EXPECT_TRUE(ddk_->Ok());
}

// Verifies GetChannel is not supported.
TEST_F(ControllerDeviceTest, GetChannel) {
  EXPECT_EQ(controller_device_->DdkAdd("test-camera-controller"), ZX_OK);
  EXPECT_EQ(controller_device_->StartThread(), ZX_OK);
  ASSERT_EQ(camera_protocol_.Bind(std::move(ddk_->FidlClient())), ZX_OK);
  camera_protocol_->GetChannel(controller_protocol_.NewRequest().TakeChannel());
  RunLoopUntilIdle();
  WaitForChannelClosure(controller_protocol_.channel());
  WaitForInterfaceClosure(camera_protocol_, ZX_ERR_PEER_CLOSED);
}

// Verifies that GetChannel2 works correctly.
TEST_F(ControllerDeviceTest, GetChannel2) {
  EXPECT_EQ(controller_device_->DdkAdd("test-camera-controller"), ZX_OK);
  EXPECT_EQ(controller_device_->StartThread(), ZX_OK);
  ASSERT_EQ(camera_protocol_.Bind(std::move(ddk_->FidlClient())), ZX_OK);
  camera_protocol_->GetChannel2(controller_protocol_.NewRequest().TakeChannel());
  camera_protocol_.set_error_handler(FailErrorHandler);
  RunLoopUntilIdle();
}

// Verifies that GetChannel2 can only have one binding.
TEST_F(ControllerDeviceTest, GetChannel2InvokeTwice) {
  EXPECT_EQ(controller_device_->DdkAdd("test-camera-controller"), ZX_OK);
  EXPECT_EQ(controller_device_->StartThread(), ZX_OK);
  ASSERT_EQ(camera_protocol_.Bind(std::move(ddk_->FidlClient())), ZX_OK);
  camera_protocol_->GetChannel2(controller_protocol_.NewRequest().TakeChannel());
  RunLoopUntilIdle();
  fuchsia::camera2::hal::ControllerPtr other_controller_protocol;
  camera_protocol_->GetChannel2(other_controller_protocol.NewRequest().TakeChannel());
  RunLoopUntilIdle();
  WaitForChannelClosure(other_controller_protocol.channel());
}

// Verifies sanity of returned device info.
TEST_F(ControllerDeviceTest, GetDeviceInfo) {
  ASSERT_NO_FATAL_FAILURE(BindControllerProtocol());
  controller_protocol_->GetDeviceInfo([](fuchsia::camera2::DeviceInfo device_info) {
    EXPECT_EQ(kCameraVendorName, device_info.vendor_name());
    EXPECT_EQ(kCameraProductName, device_info.product_name());
    EXPECT_EQ(fuchsia::camera2::DeviceType::BUILTIN, device_info.type());
  });
  RunLoopUntilIdle();
}

// Verifies sanity of returned configs.
TEST_F(ControllerDeviceTest, GetNextConfig) {
  ASSERT_NO_FATAL_FAILURE(BindControllerProtocol());
  uint32_t number_of_configs = 0;
  constexpr uint32_t kNumConfigs = 3;
  bool config_populated = false;

  while (number_of_configs != kNumConfigs) {
    controller_protocol_->GetNextConfig(
        [&](std::unique_ptr<fuchsia::camera2::hal::Config> config, zx_status_t status) {
          switch (number_of_configs) {
            case SherlockConfigs::MONITORING: {
              // Config 0 (monitoring)
              ASSERT_NE(config, nullptr);
              EXPECT_EQ(config->stream_configs.at(0).properties.stream_type(),
                        fuchsia::camera2::CameraStreamType::FULL_RESOLUTION |
                            fuchsia::camera2::CameraStreamType::MACHINE_LEARNING);
              EXPECT_EQ(config->stream_configs.at(1).properties.stream_type(),
                        fuchsia::camera2::CameraStreamType::DOWNSCALED_RESOLUTION |
                            fuchsia::camera2::CameraStreamType::MACHINE_LEARNING);
              EXPECT_EQ(config->stream_configs.at(2).properties.stream_type(),
                        fuchsia::camera2::CameraStreamType::MONITORING);
              break;
            }
            case SherlockConfigs::VIDEO: {
              // Config 1 (video conferencing)
              ASSERT_NE(config, nullptr);
              EXPECT_EQ(config->stream_configs.at(0).properties.stream_type(),
                        fuchsia::camera2::CameraStreamType::VIDEO_CONFERENCE |
                            fuchsia::camera2::CameraStreamType::MACHINE_LEARNING |
                            fuchsia::camera2::CameraStreamType::FULL_RESOLUTION);
              EXPECT_EQ(config->stream_configs.at(1).properties.stream_type(),
                        fuchsia::camera2::CameraStreamType::VIDEO_CONFERENCE);
              break;
            }
            case SherlockConfigs::VIDEO_EXTENDED_FOV: {
              // Config 2 (video conferencing with extended FOV)
              ASSERT_NE(config, nullptr);
              EXPECT_EQ(config->stream_configs.at(0).properties.stream_type(),
                        fuchsia::camera2::CameraStreamType::VIDEO_CONFERENCE |
                            fuchsia::camera2::CameraStreamType::MACHINE_LEARNING |
                            fuchsia::camera2::CameraStreamType::FULL_RESOLUTION |
                            fuchsia::camera2::CameraStreamType::EXTENDED_FOV);
              EXPECT_EQ(config->stream_configs.at(1).properties.stream_type(),
                        fuchsia::camera2::CameraStreamType::VIDEO_CONFERENCE |
                            fuchsia::camera2::CameraStreamType::EXTENDED_FOV);
              break;
            }
            default: {
              EXPECT_EQ(config, nullptr);
              EXPECT_EQ(status, ZX_ERR_STOP);
              break;
            }
          }

          config_populated = true;
          number_of_configs++;
        });

    while (!config_populated) {
      RunLoopUntilIdle();
    }
    config_populated = false;
  }
}

TEST_F(ControllerDeviceTest, CreateStreamInvalidArgs) {
  ASSERT_NO_FATAL_FAILURE(BindControllerProtocol());
  fuchsia::camera2::StreamPtr stream;
  std::unique_ptr<fuchsia::camera2::hal::Config> camera_config;
  bool configs_populated = false;
  controller_protocol_->GetNextConfig(
      [&](std::unique_ptr<fuchsia::camera2::hal::Config> config, zx_status_t status) {
        ASSERT_NE(config, nullptr);
        ASSERT_EQ(status, ZX_OK);
        configs_populated = true;
        camera_config = std::move(config);
      });
  while (!configs_populated) {
    RunLoopUntilIdle();
  }

  fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection;
  buffer_collection.buffer_count = 0;

  // Invalid config index.
  constexpr uint32_t kInvalidConfigIndex = 10;
  controller_protocol_->CreateStream(kInvalidConfigIndex, 0, 0, std::move(buffer_collection),
                                     stream.NewRequest());
  WaitForInterfaceClosure(stream, ZX_ERR_INVALID_ARGS);

  // Invalid stream index.
  controller_protocol_->CreateStream(0, camera_config->stream_configs.size(), 0,
                                     std::move(buffer_collection), stream.NewRequest());
  WaitForInterfaceClosure(stream, ZX_ERR_INVALID_ARGS);

  // Invalid format index.
  controller_protocol_->CreateStream(0, 0, camera_config->stream_configs[0].image_formats.size(),
                                     std::move(buffer_collection), stream.NewRequest());
  WaitForInterfaceClosure(stream, ZX_ERR_INVALID_ARGS);

  // Not enough buffers.
  controller_protocol_->CreateStream(0, 0, 0, std::move(buffer_collection), stream.NewRequest());
  WaitForInterfaceClosure(stream, ZX_ERR_INVALID_ARGS);
}

}  // namespace
}  // namespace camera
