// Copyright 2022 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 <drm_fourcc.h>
#include <fcntl.h>
#include <sys/mman.h>

#include <gtest/gtest.h>

#include "gbm.h"

class GbmDevice {
 public:
  void SetUp() {
    fd_ = open("/dev/magma0", O_RDWR | O_CLOEXEC);
    ASSERT_GE(fd_, 0);

    device_ = gbm_create_device(fd_);
    ASSERT_TRUE(device_);
  }

  void TearDown() {
    gbm_device_destroy(device_);
    device_ = nullptr;

    close(fd_);
    fd_ = -1;
  }

  struct gbm_device *device() { return device_; }

  int fd_ = -1;
  struct gbm_device *device_ = nullptr;
};

class MagmaGbmTest : public testing::Test {
 public:
  void SetUp() override { gbm_.SetUp(); }

  void TearDown() override { gbm_.TearDown(); }

  struct gbm_device *device() { return gbm_.device(); }

  GbmDevice gbm_;
};

constexpr uint32_t kDefaultWidth = 1920;
constexpr uint32_t kDefaultHeight = 1080;
constexpr uint32_t kDefaultFormat = GBM_FORMAT_ARGB8888;

TEST_F(MagmaGbmTest, CreateLinear) {
  std::vector<uint64_t> modifiers{DRM_FORMAT_MOD_LINEAR};
  struct gbm_bo *bo =
      gbm_bo_create_with_modifiers(device(), kDefaultWidth, kDefaultHeight, kDefaultFormat,
                                   modifiers.data(), static_cast<uint32_t>(modifiers.size()));
  ASSERT_TRUE(bo);
  EXPECT_EQ(DRM_FORMAT_MOD_LINEAR, gbm_bo_get_modifier(bo));
  gbm_bo_destroy(bo);
}

TEST_F(MagmaGbmTest, CreateIntelX) {
  std::vector<uint64_t> modifiers{I915_FORMAT_MOD_X_TILED};
  struct gbm_bo *bo =
      gbm_bo_create_with_modifiers(device(), kDefaultWidth, kDefaultHeight, kDefaultFormat,
                                   modifiers.data(), static_cast<uint32_t>(modifiers.size()));
  ASSERT_TRUE(bo);
  EXPECT_EQ(I915_FORMAT_MOD_X_TILED, gbm_bo_get_modifier(bo));
  gbm_bo_destroy(bo);
}

TEST_F(MagmaGbmTest, CreateIntelY) {
  std::vector<uint64_t> modifiers{I915_FORMAT_MOD_Y_TILED};
  struct gbm_bo *bo =
      gbm_bo_create_with_modifiers(device(), kDefaultWidth, kDefaultHeight, kDefaultFormat,
                                   modifiers.data(), static_cast<uint32_t>(modifiers.size()));
  ASSERT_TRUE(bo);
  EXPECT_EQ(I915_FORMAT_MOD_Y_TILED, gbm_bo_get_modifier(bo));
  gbm_bo_destroy(bo);
}

TEST_F(MagmaGbmTest, CreateIntelBest) {
  std::vector<uint64_t> modifiers{DRM_FORMAT_MOD_LINEAR, I915_FORMAT_MOD_X_TILED,
                                  I915_FORMAT_MOD_Y_TILED};
  struct gbm_bo *bo =
      gbm_bo_create_with_modifiers(device(), kDefaultWidth, kDefaultHeight, kDefaultFormat,
                                   modifiers.data(), static_cast<uint32_t>(modifiers.size()));
  ASSERT_TRUE(bo);
  EXPECT_EQ(I915_FORMAT_MOD_Y_TILED, gbm_bo_get_modifier(bo));
  gbm_bo_destroy(bo);
}

class MagmaGbmTestWithUsage : public MagmaGbmTest, public testing::WithParamInterface<uint32_t> {};

TEST_P(MagmaGbmTestWithUsage, Create) {
  uint32_t usage = GetParam();

  struct gbm_bo *bo = gbm_bo_create(device(), kDefaultWidth, kDefaultHeight, kDefaultFormat, usage);
  ASSERT_TRUE(bo);

  if (usage & GBM_BO_USE_LINEAR) {
    EXPECT_EQ(DRM_FORMAT_MOD_LINEAR, gbm_bo_get_modifier(bo));
  } else if (usage & GBM_BO_USE_SCANOUT) {
    EXPECT_EQ(I915_FORMAT_MOD_Y_TILED, gbm_bo_get_modifier(bo));
  } else {
    EXPECT_EQ(I915_FORMAT_MOD_Y_TILED_CCS, gbm_bo_get_modifier(bo));
  }

  gbm_bo_destroy(bo);
}

TEST_P(MagmaGbmTestWithUsage, Write) {
  uint32_t usage = GetParam();

  struct gbm_bo *bo = gbm_bo_create(device(), kDefaultWidth, kDefaultHeight, kDefaultFormat, usage);
  ASSERT_TRUE(bo);

  if (usage & GBM_BO_USE_LINEAR) {
    EXPECT_EQ(DRM_FORMAT_MOD_LINEAR, gbm_bo_get_modifier(bo));
  } else if (usage & GBM_BO_USE_SCANOUT) {
    EXPECT_EQ(I915_FORMAT_MOD_Y_TILED, gbm_bo_get_modifier(bo));
  } else {
    GTEST_SKIP();
  }

  {
    size_t size = kDefaultHeight * gbm_bo_get_stride(bo);

    void *transfer = malloc(size);

    ASSERT_TRUE(transfer != nullptr);

    // Write first line - zeros
    for (uint32_t i = 0; i < kDefaultWidth; i++) {
      reinterpret_cast<uint32_t *>(transfer)[i] = 0;
    }

    // Write remainder of lines
    for (uint32_t i = kDefaultWidth; i < kDefaultWidth * kDefaultHeight; i++) {
      reinterpret_cast<uint32_t *>(transfer)[i] = i;
    }

    gbm_bo_write(bo, transfer, size);

    free(transfer);
  }
  {
    uint32_t stride;
    void *map_data;

    void *addr = gbm_bo_map(bo, 0, 0, kDefaultWidth, 1, GBM_BO_TRANSFER_READ, &stride, &map_data);
    ASSERT_NE(addr, MAP_FAILED);

    for (uint32_t i = 0; i < kDefaultWidth; i++) {
      EXPECT_EQ(reinterpret_cast<uint32_t *>(addr)[i], 0u);
    }

    gbm_bo_unmap(bo, map_data);
  }
  {
    uint32_t stride;
    void *map_data;

    void *addr = gbm_bo_map(bo, 0, 1, kDefaultWidth, kDefaultHeight - 1, GBM_BO_TRANSFER_READ,
                            &stride, &map_data);
    ASSERT_NE(addr, MAP_FAILED);

    for (uint32_t i = 0; i < kDefaultWidth * (kDefaultHeight - 1); i++) {
      EXPECT_EQ(reinterpret_cast<uint32_t *>(addr)[i], kDefaultWidth + i);
    }

    gbm_bo_unmap(bo, map_data);
  }

  gbm_bo_destroy(bo);
}

TEST_P(MagmaGbmTestWithUsage, Import) {
  GbmDevice gbm2;
  gbm2.SetUp();

  constexpr uint32_t kPattern = 0xabcd1234;

  struct gbm_bo *bo =
      gbm_bo_create(device(), kDefaultWidth, kDefaultHeight, kDefaultFormat, GetParam());
  ASSERT_TRUE(bo);

  {
    uint32_t stride;
    void *map_data;
    void *addr = gbm_bo_map(bo, 0, 0, kDefaultWidth, kDefaultHeight, GBM_BO_TRANSFER_WRITE, &stride,
                            &map_data);
    ASSERT_NE(addr, MAP_FAILED);
    *reinterpret_cast<uint32_t *>(addr) = kPattern;
    gbm_bo_unmap(bo, map_data);
  }

  {
    // Import with specified stride (could be incorrect)
    constexpr uint32_t kImportStride = 123;
    // Import usage doesn't matter
    constexpr uint32_t kImportUsage = GBM_BO_USE_RENDERING;
    struct gbm_import_fd_data import;
    import.fd = gbm_bo_get_fd(bo);
    import.format = gbm_bo_get_format(bo);
    import.width = gbm_bo_get_width(bo);
    import.height = gbm_bo_get_height(bo);
    import.stride = kImportStride;
    EXPECT_GE(import.fd, 0);
    EXPECT_EQ(import.width, kDefaultWidth);
    EXPECT_EQ(import.height, kDefaultHeight);
    EXPECT_EQ(import.format, kDefaultFormat);

    struct gbm_bo *bo2 = gbm_bo_import(gbm2.device(), GBM_BO_IMPORT_FD, &import, kImportUsage);
    ASSERT_TRUE(bo2);

    EXPECT_EQ(gbm_bo_get_width(bo), gbm_bo_get_width(bo2));
    EXPECT_EQ(gbm_bo_get_height(bo), gbm_bo_get_height(bo2));
    EXPECT_EQ(gbm_bo_get_stride(bo), gbm_bo_get_stride(bo2));
    EXPECT_EQ(gbm_bo_get_format(bo), gbm_bo_get_format(bo2));
    EXPECT_EQ(gbm_bo_get_modifier(bo), gbm_bo_get_modifier(bo2));
    EXPECT_NE(DRM_FORMAT_MOD_INVALID, gbm_bo_get_modifier(bo2));

    {
      uint32_t stride;
      void *map_data;
      void *addr = gbm_bo_map(bo2, 0, 0, kDefaultWidth, kDefaultHeight, GBM_BO_TRANSFER_READ,
                              &stride, &map_data);
      ASSERT_NE(addr, MAP_FAILED);
      EXPECT_EQ(*reinterpret_cast<uint32_t *>(addr), kPattern);
      gbm_bo_unmap(bo, map_data);
    }

    gbm_bo_destroy(bo2);
  }
  {
    // Import with 0 stride
    constexpr uint32_t kImportStride = 0;
    // Import usage doesn't matter
    constexpr uint32_t kImportUsage = GBM_BO_USE_RENDERING;
    struct gbm_import_fd_data import;
    import.format = gbm_bo_get_format(bo);
    import.fd = gbm_bo_get_fd(bo);
    import.width = gbm_bo_get_width(bo);
    import.height = gbm_bo_get_height(bo);
    import.stride = kImportStride;
    EXPECT_GE(import.fd, 0);
    EXPECT_EQ(import.width, kDefaultWidth);
    EXPECT_EQ(import.height, kDefaultHeight);
    EXPECT_EQ(import.format, kDefaultFormat);

    struct gbm_bo *bo2 = gbm_bo_import(gbm2.device(), GBM_BO_IMPORT_FD, &import, kImportUsage);
    ASSERT_TRUE(bo2);

    EXPECT_EQ(gbm_bo_get_width(bo), gbm_bo_get_width(bo2));
    EXPECT_EQ(gbm_bo_get_height(bo), gbm_bo_get_height(bo2));
    EXPECT_EQ(gbm_bo_get_stride(bo), gbm_bo_get_stride(bo2));
    EXPECT_EQ(gbm_bo_get_format(bo), gbm_bo_get_format(bo2));
    EXPECT_EQ(gbm_bo_get_modifier(bo), gbm_bo_get_modifier(bo2));
    EXPECT_NE(DRM_FORMAT_MOD_INVALID, gbm_bo_get_modifier(bo2));

    {
      uint32_t stride;
      void *map_data;
      void *addr = gbm_bo_map(bo2, 0, 0, kDefaultWidth, kDefaultHeight, GBM_BO_TRANSFER_READ,
                              &stride, &map_data);
      ASSERT_NE(addr, MAP_FAILED);
      EXPECT_EQ(*reinterpret_cast<uint32_t *>(addr), kPattern);
      gbm_bo_unmap(bo, map_data);
    }

    gbm_bo_destroy(bo2);
  }

  gbm_bo_destroy(bo);

  gbm2.TearDown();
}

INSTANTIATE_TEST_SUITE_P(
    MagmaGbmTestWithUsage, MagmaGbmTestWithUsage,
    ::testing::Values(GBM_BO_USE_RENDERING, GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR,
                      GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT,
                      GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT,
                      GBM_BO_USE_LINEAR),
    [](testing::TestParamInfo<MagmaGbmTestWithUsage::ParamType> info) {
      if (info.param == GBM_BO_USE_RENDERING)
        return "GBM_BO_USE_RENDERING";
      if (info.param == (GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR))
        return "GBM_BO_USE_RENDERING_GBM_BO_USE_LINEAR";
      if (info.param == (GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT))
        return "GBM_BO_USE_RENDERING_GBM_BO_USE_SCANOUT";
      if (info.param == (GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT))
        return "GBM_BO_USE_RENDERING_GBM_BO_USE_LINEAR_GBM_BO_USE_SCANOUT";
      if (info.param == GBM_BO_USE_LINEAR)
        return "GBM_BO_USE_LINEAR";
      return "Unknown";
    });
