#include "testing.h"
#include "flang/ISO_Fortran_binding.h"
#include "flang/Runtime/descriptor.h"
#include "llvm/Support/raw_ostream.h"
#include <type_traits>

using namespace Fortran::runtime;
using namespace Fortran::ISO;

// CFI_CDESC_T test helpers
template <int rank> class Test_CFI_CDESC_T {
public:
  Test_CFI_CDESC_T() {}
  ~Test_CFI_CDESC_T() {}
  void Check() {
    // Test CFI_CDESC_T macro defined in section 18.5.4 of F2018 standard
    // CFI_CDESC_T must give storage that is:
    using type = decltype(dvStorage_);
    // unqualified
    MATCH(false, std::is_const<type>::value);
    MATCH(false, std::is_volatile<type>::value);
    // suitable in size
    if (rank > 0) {
      MATCH(sizeof(dvStorage_), Descriptor::SizeInBytes(rank_, false));
    } else { // C++ implementation over-allocates for rank=0 by 24bytes.
      MATCH(true, sizeof(dvStorage_) >= Descriptor::SizeInBytes(rank_, false));
    }
    // suitable in alignment
    MATCH(0,
        reinterpret_cast<std::uintptr_t>(&dvStorage_) &
            (alignof(CFI_cdesc_t) - 1));
  }

private:
  static constexpr int rank_{rank};
  CFI_CDESC_T(rank) dvStorage_;
};

template <int rank> static void TestCdescMacroForAllRanksSmallerThan() {
  static_assert(rank > 0, "rank<0!");
  Test_CFI_CDESC_T<rank> obj;
  obj.Check();
  TestCdescMacroForAllRanksSmallerThan<rank - 1>();
}

template <> void TestCdescMacroForAllRanksSmallerThan<0>() {
  Test_CFI_CDESC_T<0> obj;
  obj.Check();
}

// CFI_establish test helper
static void AddNoiseToCdesc(CFI_cdesc_t *dv, CFI_rank_t rank) {
  static const int trap{0};
  dv->rank = 16;
  // This address is not supposed to be used. Any write attempt should trigger
  // program termination
  dv->base_addr = const_cast<int *>(&trap);
  dv->elem_len = 320;
  dv->type = CFI_type_struct;
  dv->attribute = CFI_attribute_pointer;
  for (int i{0}; i < rank; i++) {
    dv->dim[i].extent = -42;
    dv->dim[i].lower_bound = -42;
    dv->dim[i].sm = -42;
  }
}

#ifdef VERBOSE
static void DumpTestWorld(const void *bAddr, CFI_attribute_t attr,
    CFI_type_t ty, std::size_t eLen, CFI_rank_t rank,
    const CFI_index_t *eAddr) {
  llvm::outs() << " base_addr: ";
  llvm::outs().write_hex(reinterpret_cast<std::intptr_t>(bAddr))
      << " attribute: " << static_cast<int>(attr)
      << " type: " << static_cast<int>(ty) << " elem_len: " << eLen
      << " rank: " << static_cast<int>(rank) << " extent: ";
  llvm::outs().write_hex(reinterpret_cast<std::intptr_t>(eAddr)) << '\n';
  llvm::outs().flush();
}
#endif

static void check_CFI_establish(CFI_cdesc_t *dv, void *base_addr,
    CFI_attribute_t attribute, CFI_type_t type, std::size_t elem_len,
    CFI_rank_t rank, const CFI_index_t extents[]) {
#ifdef VERBOSE
  DumpTestWorld(base_addr, attribute, type, elem_len, rank, extent);
#endif
  // CFI_establish reqs from F2018 section 18.5.5
  int retCode{
      CFI_establish(dv, base_addr, attribute, type, elem_len, rank, extents)};
  Descriptor *res{reinterpret_cast<Descriptor *>(dv)};
  if (retCode == CFI_SUCCESS) {
    res->Check();
    MATCH((attribute == CFI_attribute_pointer), res->IsPointer());
    MATCH((attribute == CFI_attribute_allocatable), res->IsAllocatable());
    MATCH(rank, res->rank());
    MATCH(reinterpret_cast<std::intptr_t>(dv->base_addr),
        reinterpret_cast<std::intptr_t>(base_addr));
    MATCH(true, dv->version == CFI_VERSION);
    if (base_addr != nullptr) {
      MATCH(true, res->IsContiguous());
      for (int i{0}; i < rank; ++i) {
        MATCH(extents[i], res->GetDimension(i).Extent());
      }
    }
    if (attribute == CFI_attribute_allocatable) {
      MATCH(res->IsAllocated(), false);
    }
    if (attribute == CFI_attribute_pointer) {
      if (base_addr != nullptr) {
        for (int i{0}; i < rank; ++i) {
          MATCH(0, res->GetDimension(i).LowerBound());
        }
      }
    }
    if (type == CFI_type_struct || type == CFI_type_char ||
        type == CFI_type_char16_t || type == CFI_type_char32_t ||
        type == CFI_type_other) {
      MATCH(elem_len, res->ElementBytes());
    }
  }
  // Checking failure/success according to combination of args forbidden by the
  // standard:
  int numErr{0};
  int expectedRetCode{CFI_SUCCESS};
  if (base_addr != nullptr && attribute == CFI_attribute_allocatable) {
    ++numErr;
    expectedRetCode = CFI_ERROR_BASE_ADDR_NOT_NULL;
  }
  if (rank > CFI_MAX_RANK) {
    ++numErr;
    expectedRetCode = CFI_INVALID_RANK;
  }
  if (type < 0 || type > CFI_TYPE_LAST) {
    ++numErr;
    expectedRetCode = CFI_INVALID_TYPE;
  }

  if ((type == CFI_type_struct || type == CFI_type_char ||
          type == CFI_type_char16_t || type == CFI_type_char32_t ||
          type == CFI_type_other) &&
      elem_len <= 0) {
    ++numErr;
    expectedRetCode = CFI_INVALID_ELEM_LEN;
  }
  if (rank > 0 && base_addr != nullptr && extents == nullptr) {
    ++numErr;
    expectedRetCode = CFI_INVALID_EXTENT;
  }
  if (numErr > 1) {
    MATCH(true, retCode != CFI_SUCCESS);
  } else {
    MATCH(retCode, expectedRetCode);
  }
}

static void run_CFI_establish_tests() {
  // Testing CFI_establish defined in section 18.5.5
  CFI_index_t extents[CFI_MAX_RANK];
  for (int i{0}; i < CFI_MAX_RANK; ++i) {
    extents[i] = i + 66;
  }
  CFI_CDESC_T(CFI_MAX_RANK) dv_storage;
  CFI_cdesc_t *dv{&dv_storage};
  char base;
  void *dummyAddr{&base};
  // Define test space
  CFI_attribute_t attrCases[]{
      CFI_attribute_pointer, CFI_attribute_allocatable, CFI_attribute_other};
  CFI_type_t typeCases[]{CFI_type_int, CFI_type_struct, CFI_type_double,
      CFI_type_char, CFI_type_char16_t, CFI_type_char32_t, CFI_type_other,
      CFI_TYPE_LAST + 1};
  CFI_index_t *extentCases[]{extents, nullptr};
  void *baseAddrCases[]{dummyAddr, nullptr};
  CFI_rank_t rankCases[]{0, 1, CFI_MAX_RANK, CFI_MAX_RANK + 1};
  std::size_t lenCases[]{0, 42};

  for (CFI_attribute_t attribute : attrCases) {
    for (void *base_addr : baseAddrCases) {
      for (CFI_index_t *extent : extentCases) {
        for (CFI_rank_t rank : rankCases) {
          for (CFI_type_t type : typeCases) {
            for (size_t elem_len : lenCases) {
              AddNoiseToCdesc(dv, CFI_MAX_RANK);
              check_CFI_establish(
                  dv, base_addr, attribute, type, elem_len, rank, extent);
            }
          }
        }
      }
    }
  }
  // If base_addr is null, extents shall be ignored even if rank !=0
  const int rank3d{3};
  CFI_CDESC_T(rank3d) dv3darrayStorage;
  CFI_cdesc_t *dv_3darray{&dv3darrayStorage};
  AddNoiseToCdesc(dv_3darray, rank3d); // => dv_3darray->dim[2].extent = -42
  check_CFI_establish(dv_3darray, nullptr, CFI_attribute_other, CFI_type_int, 4,
      rank3d, extents);
  MATCH(false,
      dv_3darray->dim[2].extent == 2 + 66); // extents was read
}

static void check_CFI_address(
    const CFI_cdesc_t *dv, const CFI_index_t subscripts[]) {
  // 18.5.5.2
  void *addr{CFI_address(dv, subscripts)};
  const Descriptor *desc{reinterpret_cast<const Descriptor *>(dv)};
  void *addrCheck{desc->Element<void>(subscripts)};
  MATCH(true, addr == addrCheck);
}

// Helper function to set lower bound of descriptor
static void EstablishLowerBounds(CFI_cdesc_t *dv, CFI_index_t *sub) {
  for (int i{0}; i < dv->rank; ++i) {
    dv->dim[i].lower_bound = sub[i];
  }
}

// Helper to get size without making internal compiler functions accessible
static std::size_t ByteSize(CFI_type_t ty, std::size_t size) {
  CFI_CDESC_T(0) storage;
  CFI_cdesc_t *dv{&storage};
  int retCode{
      CFI_establish(dv, nullptr, CFI_attribute_other, ty, size, 0, nullptr)};
  return retCode == CFI_SUCCESS ? dv->elem_len : 0;
}

static void run_CFI_address_tests() {
  // Test CFI_address defined in 18.5.5.2
  // Create test world
  CFI_index_t extents[CFI_MAX_RANK];
  CFI_CDESC_T(CFI_MAX_RANK) dv_storage;
  CFI_cdesc_t *dv{&dv_storage};
  char base;
  void *dummyAddr{&base};
  CFI_attribute_t attrCases[]{
      CFI_attribute_pointer, CFI_attribute_allocatable, CFI_attribute_other};
  CFI_type_t validTypeCases[]{
      CFI_type_int, CFI_type_struct, CFI_type_double, CFI_type_char};
  CFI_index_t subscripts[CFI_MAX_RANK];
  CFI_index_t negativeLowerBounds[CFI_MAX_RANK];
  CFI_index_t zeroLowerBounds[CFI_MAX_RANK];
  CFI_index_t positiveLowerBounds[CFI_MAX_RANK];
  CFI_index_t *lowerBoundCases[]{
      negativeLowerBounds, zeroLowerBounds, positiveLowerBounds};
  for (int i{0}; i < CFI_MAX_RANK; ++i) {
    negativeLowerBounds[i] = -1;
    zeroLowerBounds[i] = 0;
    positiveLowerBounds[i] = 1;
    extents[i] = i + 2;
    subscripts[i] = i + 1;
  }

  // test for scalar
  for (CFI_attribute_t attribute : attrCases) {
    for (CFI_type_t type : validTypeCases) {
      CFI_establish(dv, dummyAddr, attribute, type, 42, 0, nullptr);
      check_CFI_address(dv, nullptr);
    }
  }
  // test for arrays
  CFI_establish(dv, dummyAddr, CFI_attribute_other, CFI_type_int, 0,
      CFI_MAX_RANK, extents);
  for (CFI_index_t *lowerBounds : lowerBoundCases) {
    EstablishLowerBounds(dv, lowerBounds);
    for (CFI_type_t type : validTypeCases) {
      for (bool contiguous : {true, false}) {
        std::size_t size{ByteSize(type, 12)};
        dv->elem_len = size;
        for (int i{0}; i < dv->rank; ++i) {
          dv->dim[i].sm = size + (contiguous ? 0 : dv->elem_len);
          size = dv->dim[i].sm * dv->dim[i].extent;
        }
        for (CFI_attribute_t attribute : attrCases) {
          dv->attribute = attribute;
          check_CFI_address(dv, subscripts);
        }
      }
    }
  }
  // Test on an assumed size array.
  CFI_establish(
      dv, dummyAddr, CFI_attribute_other, CFI_type_int, 0, 3, extents);
  dv->dim[2].extent = -1;
  check_CFI_address(dv, subscripts);
}

static void check_CFI_allocate(CFI_cdesc_t *dv,
    const CFI_index_t lower_bounds[], const CFI_index_t upper_bounds[],
    std::size_t elem_len) {
  // 18.5.5.3
  // Backup descriptor data for future checks
  const CFI_rank_t rank{dv->rank};
  const std::size_t desc_elem_len{dv->elem_len};
  const CFI_attribute_t attribute{dv->attribute};
  const CFI_type_t type{dv->type};
  const void *base_addr{dv->base_addr};
  const int version{dv->version};
#ifdef VERBOSE
  DumpTestWorld(base_addr, attribute, type, elem_len, rank, nullptr);
#endif
  int retCode{CFI_allocate(dv, lower_bounds, upper_bounds, elem_len)};
  Descriptor *desc = reinterpret_cast<Descriptor *>(dv);
  if (retCode == CFI_SUCCESS) {
    // check res properties from 18.5.5.3 par 3
    MATCH(true, dv->base_addr != nullptr);
    for (int i{0}; i < rank; ++i) {
      MATCH(lower_bounds[i], dv->dim[i].lower_bound);
      MATCH(upper_bounds[i], dv->dim[i].extent + dv->dim[i].lower_bound - 1);
    }
    if (type == CFI_type_char) {
      MATCH(elem_len, dv->elem_len);
    } else {
      MATCH(true, desc_elem_len == dv->elem_len);
    }
    MATCH(true, desc->IsContiguous());
  } else {
    MATCH(true, base_addr == dv->base_addr);
  }

  // Below dv members shall not be altered by CFI_allocate regardless of
  // success/failure
  MATCH(true, attribute == dv->attribute);
  MATCH(true, rank == dv->rank);
  MATCH(true, type == dv->type);
  MATCH(true, version == dv->version);

  // Success/failure according to standard
  int numErr{0};
  int expectedRetCode{CFI_SUCCESS};
  if (rank > CFI_MAX_RANK) {
    ++numErr;
    expectedRetCode = CFI_INVALID_RANK;
  }
  if (type < 0 || type > CFI_TYPE_LAST) {
    ++numErr;
    expectedRetCode = CFI_INVALID_TYPE;
  }
  if (base_addr != nullptr && attribute == CFI_attribute_allocatable) {
    // This is less restrictive than 18.5.5.3 arg req for which pointers arg
    // shall be unassociated. However, this match ALLOCATE behavior
    // (9.7.3/9.7.4)
    ++numErr;
    expectedRetCode = CFI_ERROR_BASE_ADDR_NOT_NULL;
  }
  if (attribute != CFI_attribute_pointer &&
      attribute != CFI_attribute_allocatable) {
    ++numErr;
    expectedRetCode = CFI_INVALID_ATTRIBUTE;
  }
  if (rank > 0 && (lower_bounds == nullptr || upper_bounds == nullptr)) {
    ++numErr;
    expectedRetCode = CFI_INVALID_EXTENT;
  }

  // Memory allocation failures are unpredictable in this test.
  if (numErr == 0 && retCode != CFI_SUCCESS) {
    MATCH(true, retCode == CFI_ERROR_MEM_ALLOCATION);
  } else if (numErr > 1) {
    MATCH(true, retCode != CFI_SUCCESS);
  } else {
    MATCH(expectedRetCode, retCode);
  }
  // clean-up
  if (retCode == CFI_SUCCESS) {
    CFI_deallocate(dv);
  }
}

static void run_CFI_allocate_tests() {
  // 18.5.5.3
  // create test world
  CFI_CDESC_T(CFI_MAX_RANK) dv_storage;
  CFI_cdesc_t *dv{&dv_storage};
  char base;
  void *dummyAddr{&base};
  CFI_attribute_t attrCases[]{
      CFI_attribute_pointer, CFI_attribute_allocatable, CFI_attribute_other};
  CFI_type_t typeCases[]{CFI_type_int, CFI_type_struct, CFI_type_double,
      CFI_type_char, CFI_type_other, CFI_TYPE_LAST + 1};
  void *baseAddrCases[]{dummyAddr, nullptr};
  CFI_rank_t rankCases[]{0, 1, CFI_MAX_RANK, CFI_MAX_RANK + 1};
  std::size_t lenCases[]{0, 42};
  CFI_index_t lb1[CFI_MAX_RANK];
  CFI_index_t ub1[CFI_MAX_RANK];
  for (int i{0}; i < CFI_MAX_RANK; ++i) {
    lb1[i] = -1;
    ub1[i] = 0;
  }

  check_CFI_establish(
      dv, nullptr, CFI_attribute_other, CFI_type_int, 0, 0, nullptr);
  for (CFI_type_t type : typeCases) {
    std::size_t ty_len{ByteSize(type, 12)};
    for (CFI_attribute_t attribute : attrCases) {
      for (void *base_addr : baseAddrCases) {
        for (CFI_rank_t rank : rankCases) {
          for (size_t elem_len : lenCases) {
            dv->base_addr = base_addr;
            dv->rank = rank;
            dv->attribute = attribute;
            dv->type = type;
            dv->elem_len = ty_len;
            check_CFI_allocate(dv, lb1, ub1, elem_len);
          }
        }
      }
    }
  }
}

static void run_CFI_section_tests() {
  // simple tests
  bool testPreConditions{true};
  constexpr CFI_index_t m{5}, n{6}, o{7};
  constexpr CFI_rank_t rank{3};
  long long array[o][n][m]; // Fortran A(m,n,o)
  long long counter{1};

  for (CFI_index_t k{0}; k < o; ++k) {
    for (CFI_index_t j{0}; j < n; ++j) {
      for (CFI_index_t i{0}; i < m; ++i) {
        array[k][j][i] = counter++; // Fortran A(i,j,k)
      }
    }
  }
  CFI_CDESC_T(rank) sourceStorage;
  CFI_cdesc_t *source{&sourceStorage};
  CFI_index_t extent[rank] = {m, n, o};
  int retCode{CFI_establish(source, &array, CFI_attribute_other,
      CFI_type_long_long, 0, rank, extent)};
  testPreConditions &= (retCode == CFI_SUCCESS);

  CFI_index_t lb[rank] = {2, 5, 4};
  CFI_index_t ub[rank] = {4, 5, 6};
  CFI_index_t strides[rank] = {2, 0, 2};
  constexpr CFI_rank_t resultRank{rank - 1};

  CFI_CDESC_T(resultRank) resultStorage;
  CFI_cdesc_t *result{&resultStorage};
  retCode = CFI_establish(result, nullptr, CFI_attribute_other,
      CFI_type_long_long, 0, resultRank, nullptr);
  testPreConditions &= (retCode == CFI_SUCCESS);

  if (!testPreConditions) {
    MATCH(true, testPreConditions);
    return;
  }

  retCode = CFI_section(
      result, source, lb, ub, strides); // Fortran B = A(2:4:2, 5:5:0, 4:6:2)
  MATCH(true, retCode == CFI_SUCCESS);

  const CFI_index_t lbs0{source->dim[0].lower_bound};
  const CFI_index_t lbs1{source->dim[1].lower_bound};
  const CFI_index_t lbs2{source->dim[2].lower_bound};

  CFI_index_t resJ{result->dim[1].lower_bound};
  for (CFI_index_t k{lb[2]}; k <= ub[2]; k += strides[2]) {
    for (CFI_index_t j{lb[1]}; j <= ub[1]; j += strides[1] ? strides[1] : 1) {
      CFI_index_t resI{result->dim[0].lower_bound};
      for (CFI_index_t i{lb[0]}; i <= ub[0]; i += strides[0]) {
        // check A(i,j,k) == B(resI, resJ) == array[k-1][j-1][i-1]
        const CFI_index_t resSubcripts[]{resI, resJ};
        const CFI_index_t srcSubcripts[]{i, j, k};
        MATCH(true,
            CFI_address(source, srcSubcripts) ==
                CFI_address(result, resSubcripts));
        MATCH(true,
            CFI_address(source, srcSubcripts) ==
                &array[k - lbs2][j - lbs1][i - lbs0]);
        ++resI;
      }
    }
    ++resJ;
  }

  strides[0] = -1;
  lb[0] = 4;
  ub[0] = 2;
  retCode = CFI_section(
      result, source, lb, ub, strides); // Fortran B = A(4:2:-1, 5:5:0, 4:6:2)
  MATCH(true, retCode == CFI_SUCCESS);

  resJ = result->dim[1].lower_bound;
  for (CFI_index_t k{lb[2]}; k <= ub[2]; k += strides[2]) {
    for (CFI_index_t j{lb[1]}; j <= ub[1]; j += 1) {
      CFI_index_t resI{result->dim[1].lower_bound + result->dim[0].extent - 1};
      for (CFI_index_t i{2}; i <= 4; ++i) {
        // check A(i,j,k) == B(resI, resJ) == array[k-1][j-1][i-1]
        const CFI_index_t resSubcripts[]{resI, resJ};
        const CFI_index_t srcSubcripts[]{i, j, k};
        MATCH(true,
            CFI_address(source, srcSubcripts) ==
                CFI_address(result, resSubcripts));
        MATCH(true,
            CFI_address(source, srcSubcripts) ==
                &array[k - lbs2][j - lbs1][i - lbs0]);
        --resI;
      }
    }
    ++resJ;
  }
}

static void run_CFI_select_part_tests() {
  constexpr std::size_t name_len{5};
  typedef struct {
    double distance;
    int stars;
    char name[name_len];
  } Galaxy;

  const CFI_rank_t rank{2};
  constexpr CFI_index_t universeSize[]{2, 3};
  Galaxy universe[universeSize[1]][universeSize[0]];

  for (int i{0}; i < universeSize[1]; ++i) {
    for (int j{0}; j < universeSize[0]; ++j) {
      // Initializing Fortran var universe(j,i)
      universe[i][j].distance = j + i * 32;
      universe[i][j].stars = j * 2 + i * 64;
      universe[i][j].name[2] = static_cast<char>(j);
      universe[i][j].name[3] = static_cast<char>(i);
    }
  }

  CFI_CDESC_T(rank) resStorage, srcStorage;
  CFI_cdesc_t *result{&resStorage};
  CFI_cdesc_t *source{&srcStorage};

  bool testPreConditions{true};
  int retCode{CFI_establish(result, nullptr, CFI_attribute_other, CFI_type_int,
      sizeof(int), rank, nullptr)};
  testPreConditions &= (retCode == CFI_SUCCESS);
  retCode = CFI_establish(source, &universe, CFI_attribute_other,
      CFI_type_struct, sizeof(Galaxy), rank, universeSize);
  testPreConditions &= (retCode == CFI_SUCCESS);
  if (!testPreConditions) {
    MATCH(true, testPreConditions);
    return;
  }

  std::size_t displacement{offsetof(Galaxy, stars)};
  std::size_t elem_len{0}; // ignored
  retCode = CFI_select_part(result, source, displacement, elem_len);
  MATCH(CFI_SUCCESS, retCode);

  bool baseAddrShiftedOk{
      static_cast<char *>(source->base_addr) + displacement ==
      result->base_addr};
  MATCH(true, baseAddrShiftedOk);
  if (!baseAddrShiftedOk) {
    return;
  }

  MATCH(sizeof(int), result->elem_len);
  for (CFI_index_t j{0}; j < universeSize[1]; ++j) {
    for (CFI_index_t i{0}; i < universeSize[0]; ++i) {
      CFI_index_t subscripts[]{
          result->dim[0].lower_bound + i, result->dim[1].lower_bound + j};
      MATCH(
          i * 2 + j * 64, *static_cast<int *>(CFI_address(result, subscripts)));
    }
  }

  // Test for Fortran character type
  retCode = CFI_establish(
      result, nullptr, CFI_attribute_other, CFI_type_char, 2, rank, nullptr);
  testPreConditions &= (retCode == CFI_SUCCESS);
  if (!testPreConditions) {
    MATCH(true, testPreConditions);
    return;
  }

  displacement = offsetof(Galaxy, name) + 2;
  elem_len = 2; // not ignored this time
  retCode = CFI_select_part(result, source, displacement, elem_len);
  MATCH(CFI_SUCCESS, retCode);

  baseAddrShiftedOk = static_cast<char *>(source->base_addr) + displacement ==
      result->base_addr;
  MATCH(true, baseAddrShiftedOk);
  if (!baseAddrShiftedOk) {
    return;
  }

  MATCH(elem_len, result->elem_len);
  for (CFI_index_t j{0}; j < universeSize[1]; ++j) {
    for (CFI_index_t i{0}; i < universeSize[0]; ++i) {
      CFI_index_t subscripts[]{
          result->dim[0].lower_bound + i, result->dim[1].lower_bound + j};
      MATCH(static_cast<char>(i),
          static_cast<char *>(CFI_address(result, subscripts))[0]);
      MATCH(static_cast<char>(j),
          static_cast<char *>(CFI_address(result, subscripts))[1]);
    }
  }
}

static void run_CFI_setpointer_tests() {
  constexpr CFI_rank_t rank{3};
  CFI_CDESC_T(rank) resStorage, srcStorage;
  CFI_cdesc_t *result{&resStorage};
  CFI_cdesc_t *source{&srcStorage};
  CFI_index_t lower_bounds[rank];
  CFI_index_t extents[rank];
  for (int i{0}; i < rank; ++i) {
    lower_bounds[i] = i;
    extents[i] = 2;
  }

  char target;
  char *dummyBaseAddress{&target};
  bool testPreConditions{true};
  CFI_type_t type{CFI_type_int};
  std::size_t elem_len{ByteSize(type, 42)};
  int retCode{CFI_establish(
      result, nullptr, CFI_attribute_pointer, type, elem_len, rank, nullptr)};
  testPreConditions &= (retCode == CFI_SUCCESS);
  retCode = CFI_establish(source, dummyBaseAddress, CFI_attribute_other, type,
      elem_len, rank, extents);
  testPreConditions &= (retCode == CFI_SUCCESS);
  if (!testPreConditions) {
    MATCH(true, testPreConditions);
    return;
  }

  retCode = CFI_setpointer(result, source, lower_bounds);
  MATCH(CFI_SUCCESS, retCode);

  // The following members must be invariant
  MATCH(rank, result->rank);
  MATCH(elem_len, result->elem_len);
  MATCH(type, result->type);
  // check pointer association
  MATCH(true, result->base_addr == source->base_addr);
  for (int j{0}; j < rank; ++j) {
    MATCH(source->dim[j].extent, result->dim[j].extent);
    MATCH(source->dim[j].sm, result->dim[j].sm);
    MATCH(lower_bounds[j], result->dim[j].lower_bound);
  }
}

int main() {
  TestCdescMacroForAllRanksSmallerThan<CFI_MAX_RANK>();
  run_CFI_establish_tests();
  run_CFI_address_tests();
  run_CFI_allocate_tests();
  // TODO: test CFI_deallocate
  // TODO: test CFI_is_contiguous
  run_CFI_section_tests();
  run_CFI_select_part_tests();
  run_CFI_setpointer_tests();
  return testing::Complete();
}
