// Copyright 2017 The Chromium OS 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 <semaphore.h>

#include <list>
#include <unordered_map>

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/command_line.h>
#include <base/logging.h>
#include <base/memory/writable_shared_memory_region.h>
#include <brillo/message_loops/base_message_loop.h>
#include <gtest/gtest.h>

#include "common/libcab_test_internal.h"
#include "cros-camera/camera_algorithm_bridge.h"
#include "cros-camera/common.h"

namespace libcab_test {

class CameraAlgorithmBridgeFixture : public testing::Test,
                                     public camera_algorithm_callback_ops_t {
 public:
  const size_t kShmBufferSize = 2048;

  CameraAlgorithmBridgeFixture() : req_id_(0) {
    mojo_manager_ = cros::CameraMojoChannelManager::CreateInstance();
    CameraAlgorithmBridgeFixture::return_callback =
        CameraAlgorithmBridgeFixture::ReturnCallbackForwarder;
    bridge_ = cros::CameraAlgorithmBridge::CreateInstance(
        cros::CameraAlgorithmBackend::kTest, mojo_manager_.get());
    if (!bridge_ || bridge_->Initialize(this) != 0) {
      ADD_FAILURE() << "Failed to initialize camera algorithm bridge";
      return;
    }
    sem_init(&return_sem_, 0, 0);
  }

  CameraAlgorithmBridgeFixture(const CameraAlgorithmBridgeFixture&) = delete;
  CameraAlgorithmBridgeFixture& operator=(const CameraAlgorithmBridgeFixture&) =
      delete;

  ~CameraAlgorithmBridgeFixture() { sem_destroy(&return_sem_); }

  void Request(const std::vector<uint8_t>& req_header, int32_t buffer_handle) {
    {
      base::AutoLock l(request_map_lock_);
      request_map_[req_id_] = buffer_handle;
    }
    bridge_->Request(req_id_++, req_header, buffer_handle);
  }

  cros::CameraMojoChannelManager* GetMojoManagerInstance() {
    return mojo_manager_.get();
  }

 protected:
  static void ReturnCallbackForwarder(
      const camera_algorithm_callback_ops_t* callback_ops,
      uint32_t req_id,
      uint32_t status,
      int32_t buffer_handle) {
    if (callback_ops) {
      auto s = const_cast<CameraAlgorithmBridgeFixture*>(
          static_cast<const CameraAlgorithmBridgeFixture*>(callback_ops));
      s->ReturnCallback(req_id, status, buffer_handle);
    }
  }

  virtual void ReturnCallback(uint32_t req_id,
                              uint32_t status,
                              int32_t buffer_handle) {
    base::AutoLock l(request_map_lock_);
    if (request_map_.find(req_id) == request_map_.end() ||
        request_map_[req_id] != buffer_handle) {
      ADD_FAILURE()
          << "Invalid request id or handle received from the return callback";
      return;
    }
    status_list_.push_back(status);
    request_map_.erase(req_id);
    sem_post(&return_sem_);
  }

  // |mojo_manager_| should only be destroyed after any usage of it. So it
  // should be declared first.
  std::unique_ptr<cros::CameraMojoChannelManager> mojo_manager_;

  std::unique_ptr<cros::CameraAlgorithmBridge> bridge_;

  std::list<int32_t> status_list_;

  sem_t return_sem_;

 private:
  uint32_t req_id_;

  base::Lock request_map_lock_;

  std::unordered_map<uint32_t, int32_t> request_map_;
};

TEST_F(CameraAlgorithmBridgeFixture, BasicOperation) {
  base::WritableSharedMemoryRegion shm_region =
      base::WritableSharedMemoryRegion::Create(kShmBufferSize);
  ASSERT_TRUE(shm_region.IsValid()) << "Failed to create shared memory region";
  base::WritableSharedMemoryMapping shm_mapping = shm_region.Map();
  ASSERT_TRUE(shm_mapping.IsValid())
      << "Failed to create shared memory mapping";
  base::subtle::PlatformSharedMemoryRegion platform_shm =
      base::WritableSharedMemoryRegion::TakeHandleForSerialization(
          std::move(shm_region));
  int32_t handle = bridge_->RegisterBuffer(platform_shm.GetPlatformHandle().fd);
  ASSERT_LE(0, handle) << "Handle should be of positive value";
  std::vector<uint8_t> req_header(1, REQUEST_TEST_COMMAND_NORMAL);
  Request(req_header, handle);
  struct timespec timeout = {};
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 1;
  ASSERT_EQ(0, sem_timedwait(&return_sem_, &timeout));
  ASSERT_EQ(0, status_list_.front());
  std::vector<int32_t> handles({handle});
  bridge_->DeregisterBuffers(handles);
}

TEST_F(CameraAlgorithmBridgeFixture, InvalidFdOrHandle) {
  int32_t handle = bridge_->RegisterBuffer(-1);
  ASSERT_GT(0, handle) << "Registering invalid fd should have failed";

  base::WritableSharedMemoryRegion shm_region =
      base::WritableSharedMemoryRegion::Create(kShmBufferSize);
  ASSERT_TRUE(shm_region.IsValid()) << "Failed to create shared memory region";
  base::WritableSharedMemoryMapping shm_mapping = shm_region.Map();
  ASSERT_TRUE(shm_mapping.IsValid())
      << "Failed to create shared memory mapping";
  base::subtle::PlatformSharedMemoryRegion platform_shm =
      base::WritableSharedMemoryRegion::TakeHandleForSerialization(
          std::move(shm_region));
  handle = bridge_->RegisterBuffer(platform_shm.GetPlatformHandle().fd);
  ASSERT_LE(0, handle) << "Handle should be of positive value";
  std::vector<uint8_t> req_header(1, REQUEST_TEST_COMMAND_NORMAL);
  Request(req_header, handle - 1);
  Request(req_header, handle + 1);
  struct timespec timeout = {};
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 1;
  for (uint32_t i = 0; i < 2; i++) {
    ASSERT_EQ(0, sem_timedwait(&return_sem_, &timeout));
  }
  for (const auto& it : status_list_) {
    ASSERT_EQ(-EBADF, it);
  }
  std::vector<int32_t> handles({handle});
  bridge_->DeregisterBuffers(handles);

  // Closes the fd to fail RegisterBuffer.
  // PassPlatformHandle() passes ownership to the returned |ScopedFDPair|, while
  // get() does not transfer the ownership.
  // When the temporary variable is destructed at the end of the statement, the
  // fd is closed.
  int fd = platform_shm.PassPlatformHandle().fd.get();
  ASSERT_GT(0, bridge_->RegisterBuffer(fd))
      << "Registering invalid fd should have failed";
}

TEST_F(CameraAlgorithmBridgeFixture, MultiRequests) {
  const size_t kNumberOfFds = 256;

  std::vector<base::subtle::PlatformSharedMemoryRegion> platform_shms(
      kNumberOfFds);
  std::vector<int> handles(kNumberOfFds);
  for (uint32_t i = 0; i < kNumberOfFds; i++) {
    base::WritableSharedMemoryRegion shm_region =
        base::WritableSharedMemoryRegion::Create(kShmBufferSize);
    ASSERT_TRUE(shm_region.IsValid())
        << "Failed to create shared memory region";
    platform_shms[i] =
        base::WritableSharedMemoryRegion::TakeHandleForSerialization(
            std::move(shm_region));
    handles[i] =
        bridge_->RegisterBuffer(platform_shms[i].GetPlatformHandle().fd);
    ASSERT_LE(0, handles[i]) << "Handle should be of positive value";
  }
  for (const auto handle : handles) {
    std::vector<uint8_t> req_header(1, REQUEST_TEST_COMMAND_NORMAL);
    Request(req_header, handle);
  }
  struct timespec timeout = {};
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 1;
  for (size_t i = 0; i < handles.size(); ++i) {
    ASSERT_EQ(0, sem_timedwait(&return_sem_, &timeout));
  }
  for (const auto& it : status_list_) {
    ASSERT_EQ(0, it);
  }
  bridge_->DeregisterBuffers(handles);
}

TEST_F(CameraAlgorithmBridgeFixture, DeadLockRecovery) {
  // Create a dead lock in the algorithm.
  std::vector<uint8_t> req_header(1, REQUEST_TEST_COMMAND_DEAD_LOCK);
  Request(req_header, -1);
  struct timespec timeout = {};
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 1;
  ASSERT_NE(0, sem_timedwait(&return_sem_, &timeout));
  // Reconnect the bridge.
  bridge_ = cros::CameraAlgorithmBridge::CreateInstance(
      cros::CameraAlgorithmBackend::kTest, GetMojoManagerInstance());
  ASSERT_NE(nullptr, bridge_);
  ASSERT_EQ(0, bridge_->Initialize(this));
  base::WritableSharedMemoryRegion shm_region =
      base::WritableSharedMemoryRegion::Create(kShmBufferSize);
  ASSERT_TRUE(shm_region.IsValid()) << "Failed to create shared memory region";
  base::WritableSharedMemoryMapping shm_mapping = shm_region.Map();
  ASSERT_TRUE(shm_mapping.IsValid())
      << "Failed to create shared memory mapping";
  base::subtle::PlatformSharedMemoryRegion platform_shm =
      base::WritableSharedMemoryRegion::TakeHandleForSerialization(
          std::move(shm_region));
  int32_t handle = bridge_->RegisterBuffer(platform_shm.GetPlatformHandle().fd);
  ASSERT_LE(0, handle) << "Handle should be of positive value";
  req_header = std::vector<uint8_t>(1, REQUEST_TEST_COMMAND_NORMAL);
  Request(req_header, handle);
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 1;
  ASSERT_EQ(0, sem_timedwait(&return_sem_, &timeout));
  ASSERT_EQ(0, status_list_.front());
  std::vector<int32_t> handles({handle});
  bridge_->DeregisterBuffers(handles);
}

class CameraAlgorithmBridgeStatusFixture : public CameraAlgorithmBridgeFixture {
 public:
  CameraAlgorithmBridgeStatusFixture() {}
  CameraAlgorithmBridgeStatusFixture(
      const CameraAlgorithmBridgeStatusFixture&) = delete;
  CameraAlgorithmBridgeStatusFixture& operator=(
      const CameraAlgorithmBridgeStatusFixture&) = delete;

 protected:
  void ReturnCallback(uint32_t req_id,
                      uint32_t status,
                      int32_t buffer_handle) override {
    base::AutoLock l(hash_codes_lock_);
    if (buffer_handle < 0 ||
        static_cast<size_t>(buffer_handle) >= hash_codes_.size() ||
        hash_codes_[buffer_handle] != status) {
      ADD_FAILURE() << "Invalid status received from the return callback";
      return;
    }
    sem_post(&return_sem_);
  }

  base::Lock hash_codes_lock_;

  // Stores hashcode generated from |req_header| of the Request calls.
  std::vector<uint32_t> hash_codes_;
};

static int GenerateRandomHeader(uint32_t max_header_len,
                                std::vector<uint8_t>* header) {
  if (max_header_len == 0 || !header) {
    return -EINVAL;
  }
  static unsigned int seed = time(NULL) + getpid();
  header->resize((rand_r(&seed) % max_header_len) + 1);
  for (auto& it : *header) {
    it = rand_r(&seed);
  }
  return 0;
}

TEST_F(CameraAlgorithmBridgeStatusFixture, VerifyReturnStatus) {
  const uint32_t kNumberOfTests = 256;
  const uint32_t kMaxReqHeaderSize = 64;
  for (uint32_t i = 0; i <= kNumberOfTests; i++) {
    std::vector<uint8_t> req_header;
    GenerateRandomHeader(kMaxReqHeaderSize, &req_header);
    req_header[0] = REQUEST_TEST_COMMAND_VERIFY_STATUS;
    {
      base::AutoLock l(hash_codes_lock_);
      hash_codes_.push_back(SimpleHash(req_header.data(), req_header.size()));
    }
    Request(req_header, i);
  }
  struct timespec timeout = {};
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 1;
  for (uint32_t i = 0; i <= kNumberOfTests; i++) {
    ASSERT_EQ(0, sem_timedwait(&return_sem_, &timeout));
  }
}

}  // namespace libcab_test

int main(int argc, char** argv) {
  static base::AtExitManager exit_manager;

  // Set up logging so we can enable VLOGs with -v / --vmodule.
  base::CommandLine::Init(argc, argv);
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
  LOG_ASSERT(logging::InitLogging(settings));

  brillo::BaseMessageLoop message_loop;
  message_loop.SetAsCurrent();

  // Initialize and run all tests
  ::testing::InitGoogleTest(&argc, argv);
  int result = RUN_ALL_TESTS();

  return result;
}
