// Copyright 2018 The Chromium 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 "ui/gfx/linux/test/mock_gbm_device.h"

#include <xf86drm.h>
#include <memory>
#include <utility>

#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/numerics/safe_math.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/gfx/linux/gbm_buffer.h"

namespace ui {
namespace {

base::ScopedFD MakeFD() {
  base::FilePath temp_path;
  if (!base::CreateTemporaryFile(&temp_path))
    return {};
  auto file =
      base::File(temp_path, base::File::FLAG_READ | base::File::FLAG_WRITE |
                                base::File::FLAG_CREATE_ALWAYS);
  return base::ScopedFD(file.TakePlatformFile());
}

class MockGbmBuffer final : public ui::GbmBuffer {
 public:
  MockGbmBuffer(uint32_t format,
                uint32_t flags,
                uint64_t modifier,
                const gfx::Size& size,
                std::vector<gfx::NativePixmapPlane> planes,
                std::vector<uint32_t> handles)
      : format_(format),
        format_modifier_(modifier),
        flags_(flags),
        size_(size),
        planes_(std::move(planes)),
        handles_(std::move(handles)) {}

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

  ~MockGbmBuffer() override = default;

  uint32_t GetFormat() const override { return format_; }
  uint64_t GetFormatModifier() const override { return format_modifier_; }
  uint32_t GetFlags() const override { return flags_; }
  gfx::Size GetSize() const override { return size_; }
  gfx::BufferFormat GetBufferFormat() const override {
    return ui::GetBufferFormatFromFourCCFormat(format_);
  }
  bool AreFdsValid() const override {
    if (planes_.empty())
      return false;

    for (const auto& plane : planes_) {
      if (!plane.fd.is_valid())
        return false;
    }
    return true;
  }
  size_t GetNumPlanes() const override { return planes_.size(); }
  int GetPlaneFd(size_t plane) const override {
    return planes_[plane].fd.get();
  }
  uint32_t GetPlaneStride(size_t plane) const override {
    DCHECK_LT(plane, planes_.size());
    return planes_[plane].stride;
  }
  size_t GetPlaneOffset(size_t plane) const override {
    DCHECK_LT(plane, planes_.size());
    return planes_[plane].offset;
  }
  size_t GetPlaneSize(size_t plane) const override {
    DCHECK_LT(plane, planes_.size());
    return static_cast<size_t>(planes_[plane].size);
  }
  uint32_t GetPlaneHandle(size_t plane) const override {
    DCHECK_LT(plane, planes_.size());
    return handles_[plane];
  }
  uint32_t GetHandle() const override { return GetPlaneHandle(0); }
  gfx::NativePixmapHandle ExportHandle() const override {
    NOTIMPLEMENTED();
    return gfx::NativePixmapHandle();
  }

  sk_sp<SkSurface> GetSurface() override { return nullptr; }

 private:
  uint32_t format_ = 0;
  uint64_t format_modifier_ = 0;
  uint32_t flags_ = 0;
  gfx::Size size_;
  std::vector<gfx::NativePixmapPlane> planes_;
  std::vector<uint32_t> handles_;
};

}  // namespace

MockGbmDevice::MockGbmDevice() = default;

MockGbmDevice::~MockGbmDevice() = default;

void MockGbmDevice::set_allocation_failure(bool should_fail_allocations) {
  should_fail_allocations_ = should_fail_allocations;
}

std::vector<uint64_t> MockGbmDevice::GetSupportedModifiers() const {
  return supported_modifiers_;
}

std::unique_ptr<GbmBuffer> MockGbmDevice::CreateBuffer(uint32_t format,
                                                       const gfx::Size& size,
                                                       uint32_t flags) {
  if (should_fail_allocations_)
    return nullptr;

  return CreateBufferWithModifiers(format, size, flags, {});
}

std::unique_ptr<GbmBuffer> MockGbmDevice::CreateBufferWithModifiers(
    uint32_t format,
    const gfx::Size& size,
    uint32_t flags,
    const std::vector<uint64_t>& modifiers) {
  if (should_fail_allocations_)
    return nullptr;

  uint32_t bytes_per_pixel;
  switch (format) {
    case DRM_FORMAT_XRGB8888:
    case DRM_FORMAT_ARGB8888:
    case DRM_FORMAT_ARGB2101010:
    case DRM_FORMAT_ABGR2101010:
      bytes_per_pixel = 4;
      break;
    case DRM_FORMAT_NV12:
      bytes_per_pixel = 2;
      break;
    default:
      NOTREACHED() << "Unsupported format: " << format;
      return nullptr;
  }

  uint64_t format_modifier =
      modifiers.empty() ? DRM_FORMAT_MOD_NONE : modifiers.back();

  if (!base::Contains(supported_modifiers_, format_modifier)) {
    PLOG(ERROR) << "Unsupported format modifier: " << std::hex
                << format_modifier;
    return nullptr;
  }

  uint32_t width = base::checked_cast<uint32_t>(size.width());
  uint32_t height = base::checked_cast<uint32_t>(size.height());
  uint32_t plane_stride = base::CheckMul(bytes_per_pixel, width).ValueOrDie();
  uint32_t plane_size = base::CheckMul(plane_stride, height).ValueOrDie();
  uint32_t plane_offset = 0;

  std::vector<gfx::NativePixmapPlane> planes;
  planes.emplace_back(plane_stride, plane_offset, plane_size, MakeFD());
  std::vector<uint32_t> handles;
  handles.push_back(next_handle_++);

  return std::make_unique<MockGbmBuffer>(format, flags, format_modifier, size,
                                         std::move(planes), std::move(handles));
}

std::unique_ptr<GbmBuffer> MockGbmDevice::CreateBufferFromHandle(
    uint32_t format,
    const gfx::Size& size,
    gfx::NativePixmapHandle handle) {
  NOTREACHED();
  return nullptr;
}

}  // namespace ui
