//===- unittests/Lex/HeaderMapTestUtils.h - HeaderMap utils -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===--------------------------------------------------------------===//

#ifndef LLVM_CLANG_UNITTESTS_LEX_HEADERMAPTESTUTILS_H
#define LLVM_CLANG_UNITTESTS_LEX_HEADERMAPTESTUTILS_H

#include "clang/Basic/CharInfo.h"
#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/HeaderMapTypes.h"
#include "llvm/Support/SwapByteOrder.h"
#include <cassert>

namespace clang {
namespace test {

// Lay out a header file for testing.
template <unsigned NumBuckets, unsigned NumBytes> struct HMapFileMock {
  HMapHeader Header;
  HMapBucket Buckets[NumBuckets];
  unsigned char Bytes[NumBytes];

  void init() {
    memset(this, 0, sizeof(HMapFileMock));
    Header.Magic = HMAP_HeaderMagicNumber;
    Header.Version = HMAP_HeaderVersion;
    Header.NumBuckets = NumBuckets;
    Header.StringsOffset = sizeof(Header) + sizeof(Buckets);
  }

  void swapBytes() {
    using llvm::sys::getSwappedBytes;
    Header.Magic = getSwappedBytes(Header.Magic);
    Header.Version = getSwappedBytes(Header.Version);
    Header.NumBuckets = getSwappedBytes(Header.NumBuckets);
    Header.StringsOffset = getSwappedBytes(Header.StringsOffset);
  }

  std::unique_ptr<llvm::MemoryBuffer> getBuffer() {
    return llvm::MemoryBuffer::getMemBuffer(
        StringRef(reinterpret_cast<char *>(this), sizeof(HMapFileMock)),
        "header",
        /* RequresNullTerminator */ false);
  }
};

template <class FileTy> struct HMapFileMockMaker {
  FileTy &File;
  unsigned SI = 1;
  unsigned BI = 0;
  HMapFileMockMaker(FileTy &File) : File(File) {}

  unsigned addString(StringRef S) {
    assert(SI + S.size() + 1 <= sizeof(File.Bytes));
    std::copy(S.begin(), S.end(), File.Bytes + SI);
    auto OldSI = SI;
    SI += S.size() + 1;
    return OldSI;
  }

  void addBucket(StringRef Str, unsigned Key, unsigned Prefix,
                 unsigned Suffix) {
    addBucket(getHash(Str), Key, Prefix, Suffix);
  }

  void addBucket(unsigned Hash, unsigned Key, unsigned Prefix,
                 unsigned Suffix) {
    assert(!(File.Header.NumBuckets & (File.Header.NumBuckets - 1)));
    unsigned I = Hash & (File.Header.NumBuckets - 1);
    do {
      if (!File.Buckets[I].Key) {
        File.Buckets[I].Key = Key;
        File.Buckets[I].Prefix = Prefix;
        File.Buckets[I].Suffix = Suffix;
        ++File.Header.NumEntries;
        return;
      }
      ++I;
      I &= File.Header.NumBuckets - 1;
    } while (I != (Hash & (File.Header.NumBuckets - 1)));
    llvm_unreachable("no empty buckets");
  }

  // The header map hash function.
  static unsigned getHash(StringRef Str) {
    unsigned Result = 0;
    for (char C : Str)
      Result += toLowercase(C) * 13;
    return Result;
  }
};

} // namespace test
} // namespace clang

#endif
