// 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 <lib/dma-buffer/buffer.h>
#include <lib/fake-object/object.h>

#include <map>

#include <zxtest/zxtest.h>

namespace dma_buffer {

const zx::bti kFakeBti(42);

struct VmoMetadata {
  size_t size = 0;
  uint32_t alignment_log2 = 0;
  zx_handle_t bti_handle = ZX_HANDLE_INVALID;
  uint32_t cache_policy = 0;
  zx_paddr_t start_phys = 0;
  void* virt = nullptr;
  bool contiguous = false;
};

struct SyscallState {
  std::map<zx_handle_t, VmoMetadata> vmos;
  uint64_t current_phys = 0;
};

static SyscallState syscall_state;

extern "C" {
zx_status_t zx_vmo_create_contiguous(zx_handle_t bti_handle, size_t size, uint32_t alignment_log2,
                                     zx_handle_t* out) {
  zx_status_t status = zx_vmo_create(size, 0, out);
  if (status != ZX_OK) {
    return status;
  }
  VmoMetadata meta;
  meta.alignment_log2 = alignment_log2;
  meta.bti_handle = bti_handle;
  meta.size = size;
  syscall_state.vmos[*out] = meta;
  return ZX_OK;
}

zx_status_t zx_vmo_create(uint64_t size, uint32_t options, zx_handle_t* out) {
  zx_status_t status = REAL_SYSCALL(zx_vmo_create)(size, options, out);
  if (status != ZX_OK) {
    return status;
  }
  VmoMetadata meta;
  meta.size = size;
  syscall_state.vmos[*out] = meta;
  return ZX_OK;
}

zx_status_t zx_vmar_map(zx_handle_t handle, zx_vm_option_t options, uint64_t vmar_offset,
                        zx_handle_t vmo, uint64_t vmo_offset, uint64_t len,
                        zx_vaddr_t* mapped_addr) {
  auto record = syscall_state.vmos.find(vmo);
  zx_status_t status =
      REAL_SYSCALL(zx_vmar_map)(handle, options, vmar_offset, vmo, vmo_offset, len, mapped_addr);
  if (record != syscall_state.vmos.end()) {
    record->second.virt = reinterpret_cast<void*>(*mapped_addr);
  }
  return status;
}

zx_status_t zx_vmo_set_cache_policy(zx_handle_t handle, uint32_t cache_policy) {
  syscall_state.vmos[handle].cache_policy = cache_policy;
  return ZX_OK;
}

zx_status_t zx_bti_pin(zx_handle_t bti_handle, uint32_t options, zx_handle_t vmo, uint64_t offset,
                       uint64_t size, zx_paddr_t* addrs, size_t addrs_count, zx_handle_t* out) {
  if (bti_handle != kFakeBti.get()) {
    return ZX_ERR_BAD_HANDLE;
  }
  syscall_state.vmos[vmo].start_phys = syscall_state.current_phys;
  *addrs = syscall_state.current_phys;
  syscall_state.current_phys += syscall_state.vmos[vmo].size;
  *out = ZX_HANDLE_INVALID;
  return ZX_OK;
}

zx_status_t zx_handle_close(zx_handle_t handle) {
  auto record = syscall_state.vmos.find(handle);
  if (record == syscall_state.vmos.end()) {
    return REAL_SYSCALL(zx_handle_close)(handle);
  }
  syscall_state.vmos.erase(record);
  return ZX_OK;
}
}

TEST(DmaBufferTests, InitWithCacheEnabled) {
  std::unique_ptr<ContiguousBuffer> buffer;
  auto factory = CreateBufferFactory();
  ASSERT_OK(factory->CreateContiguous(kFakeBti, ZX_PAGE_SIZE * 4, 2, &buffer));
  auto& state = syscall_state.vmos.begin()->second;
  ASSERT_EQ(state.alignment_log2, 2);
  ASSERT_EQ(state.bti_handle, kFakeBti.get());
  ASSERT_EQ(state.cache_policy, 0);
  ASSERT_EQ(state.size, ZX_PAGE_SIZE * 4);
  ASSERT_EQ(buffer->virt(), state.virt);
  ASSERT_EQ(buffer->size(), state.size);
  ASSERT_EQ(buffer->phys(), state.start_phys);
}

TEST(DmaBufferTests, InitWithCacheDisabled) {
  std::unique_ptr<PagedBuffer> buffer;
  auto factory = CreateBufferFactory();
  ASSERT_OK(factory->CreatePaged(kFakeBti, ZX_PAGE_SIZE, false, &buffer));
  auto& state = syscall_state.vmos.begin()->second;
  ASSERT_EQ(state.alignment_log2, 0);
  ASSERT_EQ(state.cache_policy, ZX_CACHE_POLICY_UNCACHED_DEVICE);
  ASSERT_EQ(state.size, ZX_PAGE_SIZE);
  ASSERT_EQ(buffer->virt(), state.virt);
  ASSERT_EQ(buffer->size(), state.size);
  ASSERT_EQ(buffer->phys()[0], state.start_phys);
}

TEST(DmaBufferTests, InitCachedMultiPageBuffer) {
  std::unique_ptr<ContiguousBuffer> buffer;
  auto factory = CreateBufferFactory();
  ASSERT_OK(factory->CreateContiguous(kFakeBti, ZX_PAGE_SIZE * 4, 0, &buffer));
  auto& state = syscall_state.vmos.begin()->second;
  ASSERT_EQ(state.alignment_log2, 0);
  ASSERT_EQ(state.cache_policy, 0);
  ASSERT_EQ(state.bti_handle, kFakeBti.get());
  ASSERT_EQ(state.size, ZX_PAGE_SIZE * 4);
  ASSERT_EQ(buffer->virt(), state.virt);
  ASSERT_EQ(buffer->size(), state.size);
  ASSERT_EQ(buffer->phys(), state.start_phys);
}

}  // namespace dma_buffer
