#include "mock.h"
#include "pa_tz_api.h"
#include "kernel_access.h"
#include <string.h>

enum {
  kTestSize = 16384
};

static uint8_t g_mock_buffer[kTestSize];

// For testing aligned address of memory
static PhysicalAddress kTestPhysicalAddress = (PhysicalAddress)g_mock_buffer;

static PaTzResult g_mock_result = PA_TZ_SUCCESS;

static uint32_t g_mock_call_map_counter = 0;
static uint32_t g_mock_call_unmap_counter = 0;
static uint32_t g_mock_call_kernel_virt_to_phys_counter = 0;

/*
 * Mocked functions
 */
PaTzResult PlatformMapRegion(PhysicalAddress phys, size_t size,
                          MemoryAccessType type, void **virt) {
  *virt = (void *)kTestPhysicalAddress;

  g_mock_call_map_counter++;

  return g_mock_result;
}

PaTzResult PlatformUnmapRegion(void *virt, size_t size) {
  g_mock_call_unmap_counter++;

  return g_mock_result;
}

PhysicalAddress KernelVirtToPhys(KernelAddress kernel_virt) {
  g_mock_call_kernel_virt_to_phys_counter++;

  return (PhysicalAddress)kernel_virt;
}

uint32_t IsPhysicalAddress(PhysicalAddress phys) {
  return ((phys >= kTestPhysicalAddress &&
         phys < kTestPhysicalAddress + kTestSize) ? 1 : 0);
}

void InitMocks() {
  g_mock_call_map_counter = 0;
  g_mock_call_unmap_counter = 0;
  g_mock_call_kernel_virt_to_phys_counter = 0;

  kTestPhysicalAddress = AlignToPageUp((uint64_t)g_mock_buffer);

  memset(g_mock_buffer, 0xAB, sizeof(g_mock_buffer));
}

void DeinitMocks() {

}

uint32_t GetMockCallMapCounter() {
  return g_mock_call_map_counter;
}

uint32_t GetMockCallUnmapCounter() {
  return g_mock_call_unmap_counter;
}

uint32_t GetMockCallVirtToPhysCounter() {
  return g_mock_call_kernel_virt_to_phys_counter;
}

uint32_t GetTestSize() {
  return kTestSize;
}

uint8_t *GetMockBuffer(int offset) {
  return &g_mock_buffer[offset];
}

PhysicalAddress GetTestPhysicalAddress() {
  return kTestPhysicalAddress;
}
