/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/****************************************************************************

   HdrHeap.h

   Description:


 ****************************************************************************/

#pragma once

#include "tscore/Ptr.h"
#include "tscore/ink_assert.h"
#include "tscore/Scalar.h"
#include "HdrToken.h"

// Objects in the heap must currently be aligned to 8 byte boundaries,
// so their (address & HDR_PTR_ALIGNMENT_MASK) == 0

static constexpr size_t HDR_PTR_SIZE           = sizeof(uint64_t);
static constexpr size_t HDR_PTR_ALIGNMENT_MASK = HDR_PTR_SIZE - 1L;
using HdrHeapMarshalBlocks                     = ts::Scalar<HDR_PTR_SIZE>;

// A many of the operations regarding read-only str
//  heaps are hand unrolled in the code.  Changing
//  this value requires a full pass through HdrBuf.cc
//  to fix the unrolled operations
static constexpr unsigned HDR_BUF_RONLY_HEAPS = 3;

class IOBufferBlock;

enum {
  HDR_HEAP_OBJ_EMPTY            = 0,
  HDR_HEAP_OBJ_RAW              = 1,
  HDR_HEAP_OBJ_URL              = 2,
  HDR_HEAP_OBJ_HTTP_HEADER      = 3,
  HDR_HEAP_OBJ_MIME_HEADER      = 4,
  HDR_HEAP_OBJ_FIELD_BLOCK      = 5,
  HDR_HEAP_OBJ_FIELD_STANDALONE = 6, // not a type that lives in HdrHeaps
  HDR_HEAP_OBJ_FIELD_SDK_HANDLE = 7, // not a type that lives in HdrHeaps

  HDR_HEAP_OBJ_MAGIC = 0x0FEEB1E0
};

struct HdrHeapObjImpl {
  uint32_t m_type : 8;
  uint32_t m_length : 20;
  uint32_t m_obj_flags : 4;
};

/*-------------------------------------------------------------------------
  -------------------------------------------------------------------------*/

extern void obj_describe(HdrHeapObjImpl *obj, bool recurse);

inline int
obj_is_aligned(HdrHeapObjImpl *obj)
{
  return (((((uintptr_t)obj) & HDR_PTR_ALIGNMENT_MASK) == 0) && ((obj->m_length & HDR_PTR_ALIGNMENT_MASK) == 0));
}

inline void
obj_clear_data(HdrHeapObjImpl *obj)
{
  char *ptr      = (char *)obj;
  int hdr_length = sizeof(HdrHeapObjImpl);
  memset(ptr + hdr_length, '\0', obj->m_length - hdr_length);
}

inline void
obj_copy_data(HdrHeapObjImpl *s_obj, HdrHeapObjImpl *d_obj)
{
  char *src, *dst;

  ink_assert((s_obj->m_length == d_obj->m_length) && (s_obj->m_type == d_obj->m_type));

  int hdr_length = sizeof(HdrHeapObjImpl);
  src            = (char *)s_obj + hdr_length;
  dst            = (char *)d_obj + hdr_length;
  memcpy(dst, src, d_obj->m_length - hdr_length);
}

inline void
obj_copy(HdrHeapObjImpl *s_obj, char *d_addr)
{
  memcpy(d_addr, (char *)s_obj, s_obj->m_length);
}

inline void
obj_init_header(HdrHeapObjImpl *obj, uint32_t type, uint32_t nbytes, uint32_t obj_flags)
{
  obj->m_type      = type;
  obj->m_length    = nbytes;
  obj->m_obj_flags = obj_flags;
}

/*-------------------------------------------------------------------------
  -------------------------------------------------------------------------*/

enum {
  HDR_BUF_MAGIC_ALIVE     = 0xabcdfeed,
  HDR_BUF_MAGIC_MARSHALED = 0xdcbafeed,
  HDR_BUF_MAGIC_DEAD      = 0xabcddead,
  HDR_BUF_MAGIC_CORRUPT   = 0xbadbadcc
};

class HdrStrHeap : public RefCountObj
{
public:
  static constexpr int DEFAULT_SIZE = 2048;

  void free() override;

  char *allocate(int nbytes);
  char *expand(char *ptr, int old_size, int new_size);
  int space_avail();

  uint32_t m_heap_size;
  char *m_free_start;
  uint32_t m_free_size;

  bool contains(const char *str) const;
};

inline bool
HdrStrHeap::contains(const char *str) const
{
  return reinterpret_cast<char const *>(this + 1) <= str && str < reinterpret_cast<char const *>(this) + m_heap_size;
}

struct StrHeapDesc {
  StrHeapDesc() = default;

  Ptr<RefCountObj> m_ref_count_ptr;
  char const *m_heap_start = nullptr;
  int32_t m_heap_len       = 0;
  bool m_locked            = false;

  bool
  contains(const char *str) const
  {
    return (str >= m_heap_start && str < (m_heap_start + m_heap_len));
  }
};

class HdrHeap
{
public:
  static constexpr int DEFAULT_SIZE = 2048;

  void init();
  inkcoreapi void destroy();

  // PtrHeap allocation
  HdrHeapObjImpl *allocate_obj(int nbytes, int type);
  void deallocate_obj(HdrHeapObjImpl *obj);

  // StrHeap allocation
  char *allocate_str(int nbytes);
  char *expand_str(const char *old_str, int old_len, int new_len);
  char *duplicate_str(const char *str, int nbytes);
  void free_string(const char *s, int len);

  // Marshalling
  inkcoreapi int marshal_length();
  inkcoreapi int marshal(char *buf, int length);
  int unmarshal(int buf_length, int obj_type, HdrHeapObjImpl **found_obj, RefCountObj *block_ref);
  /// Computes the valid data size of an unmarshalled instance.
  /// Callers should round up to HDR_PTR_SIZE to get the actual footprint.
  int unmarshal_size() const; // TBD - change this name, it's confusing.
  // One option - overload marshal_length to return this value if @a magic is HDR_BUF_MAGIC_MARSHALED.

  void inherit_string_heaps(const HdrHeap *inherit_from);
  int attach_block(IOBufferBlock *b, const char *use_start);
  void set_ronly_str_heap_end(int slot, const char *end);

  // Lock read only str heaps so that can't be moved around
  //  by a heap consolidation.  Does NOT lock for Multi-Threaded
  //  access!
  void
  lock_ronly_str_heap(unsigned i)
  {
    m_ronly_heap[i].m_locked = true;
  }

  void
  unlock_ronly_str_heap(unsigned i)
  {
    m_ronly_heap[i].m_locked = false;
    // INKqa11238
    // Move slot i to the first available slot in m_ronly_heap[].
    // The move is necessary because the rest of the code assumes
    // heaps are always allocated in order.
    for (unsigned j = 0; j < i; j++) {
      if (m_ronly_heap[j].m_heap_start == nullptr) {
        // move slot i to slot j
        m_ronly_heap[j].m_ref_count_ptr = m_ronly_heap[i].m_ref_count_ptr;
        m_ronly_heap[j].m_heap_start    = m_ronly_heap[i].m_heap_start;
        m_ronly_heap[j].m_heap_len      = m_ronly_heap[i].m_heap_len;
        m_ronly_heap[j].m_locked        = m_ronly_heap[i].m_locked;
        m_ronly_heap[i].m_ref_count_ptr = nullptr;
        m_ronly_heap[i].m_heap_start    = nullptr;
        m_ronly_heap[i].m_heap_len      = 0;
        m_ronly_heap[i].m_locked        = false;
        break; // Did the move, time to go.
      }
    }
  }

  // Working function to copy strings into a new heap
  // Unlike the HDR_MOVE_STR macro, this function will call
  // allocate_str which will update the new_heap to create more space
  // if there is not originally sufficient space
  inline std::string_view
  localize(const std::string_view &string)
  {
    auto length = string.length();
    if (length > 0) {
      char *new_str = this->allocate_str(length);
      if (new_str) {
        memcpy(new_str, string.data(), length);
      } else {
        length = 0;
      }
      return {new_str, length};
    }
    return {nullptr, 0};
  }

  // Sanity Check Functions
  void sanity_check_strs();
  bool check_marshalled(uint32_t buf_length);

  // Debugging functions
  void dump_heap(int len = -1);

  uint32_t m_magic;
  char *m_free_start;
  char *m_data_start;
  uint32_t m_size;

  bool m_writeable;

  // Overflow block ptr
  //   Overflow blocks are necessary because we can
  //     run out of space in the header heap and the
  //     heap is not rellocatable
  //   Overflow blocks have the HdrHeap full structure
  //    header on them, although only first block can
  //    point to string heaps
  HdrHeap *m_next;

  // HdrBuf heap pointers
  uint32_t m_free_size;

  int demote_rw_str_heap();
  void coalesce_str_heaps(int incoming_size = 0);
  void evacuate_from_str_heaps(HdrStrHeap *new_heap);
  size_t required_space_for_evacuation();
  bool attach_str_heap(char const *h_start, int h_len, RefCountObj *h_ref_obj, int *index);

  uint64_t total_used_size() const;

  /** Struct to prevent garbage collection on heaps.
      This bumps the reference count to the heap containing the pointer
      while the instance of this class exists. When it goes out of scope
      the reference is dropped. This is useful inside a method or block
      to keep the required heap data around until leaving the scope.
  */
  struct HeapGuard {
    /// Construct the protection.
    HeapGuard(HdrHeap *heap, const char *str)
    {
      if (heap->m_read_write_heap && heap->m_read_write_heap->contains(str)) {
        m_ptr = heap->m_read_write_heap.get();
      } else {
        for (auto &i : heap->m_ronly_heap) {
          if (i.contains(str)) {
            m_ptr = i.m_ref_count_ptr;
            break;
          }
        }
      }
    }

    // There's no need to have a destructor here, the default dtor will take care of
    // releasing the (potentially) locked heap.

    /// The heap we protect (if any)
    Ptr<RefCountObj> m_ptr;
  };

  // String Heap access
  Ptr<HdrStrHeap> m_read_write_heap;
  StrHeapDesc m_ronly_heap[HDR_BUF_RONLY_HEAPS];
  int m_lost_string_space;
};

static constexpr HdrHeapMarshalBlocks HDR_HEAP_HDR_SIZE{ts::round_up(sizeof(HdrHeap))};
static constexpr size_t HDR_MAX_ALLOC_SIZE = HdrHeap::DEFAULT_SIZE - HDR_HEAP_HDR_SIZE;

inline void
HdrHeap::free_string(const char *s, int len)
{
  if (s && len > 0) {
    m_lost_string_space += len;
  }
}

inline int
HdrHeap::unmarshal_size() const
{
  return m_size + m_ronly_heap[0].m_heap_len;
}

//
struct MarshalXlate {
  char const *start  = nullptr;
  char const *end    = nullptr;
  char const *offset = nullptr;
  MarshalXlate() {}
};

struct HeapCheck {
  char const *start;
  char const *end;
};

// Nasty macro to do string marshalling
#define HDR_MARSHAL_STR(ptr, table, nentries)                 \
  if (ptr) {                                                  \
    int found = 0;                                            \
    for (int i = 0; i < nentries; i++) {                      \
      if (ptr >= table[i].start && ptr <= table[i].end) {     \
        ptr   = (((char *)ptr) - (uintptr_t)table[i].offset); \
        found = 1;                                            \
        break;                                                \
      }                                                       \
    }                                                         \
    ink_assert(found);                                        \
    if (found == 0) {                                         \
      return -1;                                              \
    }                                                         \
  }

// Nasty macro to do string marshalling
#define HDR_MARSHAL_STR_1(ptr, table)                       \
  if (ptr) {                                                \
    int found = 0;                                          \
    if (ptr >= table[0].start && ptr <= table[0].end) {     \
      ptr   = (((char *)ptr) - (uintptr_t)table[0].offset); \
      found = 1;                                            \
    }                                                       \
    ink_assert(found);                                      \
    if (found == 0) {                                       \
      return -1;                                            \
    }                                                       \
  }

#define HDR_MARSHAL_PTR(ptr, type, table, nentries)                       \
  if (ptr) {                                                              \
    int found = 0;                                                        \
    for (int i = 0; i < nentries; i++) {                                  \
      if ((char *)ptr >= table[i].start && (char *)ptr <= table[i].end) { \
        ptr   = (type *)(((char *)ptr) - (uintptr_t)table[i].offset);     \
        found = 1;                                                        \
        break;                                                            \
      }                                                                   \
    }                                                                     \
    ink_assert(found);                                                    \
    if (found == 0) {                                                     \
      return -1;                                                          \
    }                                                                     \
  }

#define HDR_MARSHAL_PTR_1(ptr, type, table)                             \
  if (ptr) {                                                            \
    int found = 0;                                                      \
    if ((char *)ptr >= table[0].start && (char *)ptr <= table[0].end) { \
      ptr   = (type *)(((char *)ptr) - (uintptr_t)table[0].offset);     \
      found = 1;                                                        \
    }                                                                   \
    ink_assert(found);                                                  \
    if (found == 0) {                                                   \
      return -1;                                                        \
    }                                                                   \
  }

#define HDR_UNMARSHAL_STR(ptr, offset) \
  if (ptr) {                           \
    ptr = ((char *)ptr) + offset;      \
  }

#define HDR_UNMARSHAL_PTR(ptr, type, offset) \
  if (ptr) {                                 \
    ptr = (type *)(((char *)ptr) + offset);  \
  }

// Nasty macro to do string evacuation.  Assumes
//   new heap = new_heap
#define HDR_MOVE_STR(str, len)                 \
  {                                            \
    if (str) {                                 \
      char *new_str = new_heap->allocate(len); \
      if (new_str)                             \
        memcpy(new_str, str, len);             \
      str = new_str;                           \
    }                                          \
  }

// Nasty macro to do verify all strings it
//   in attached heaps
#define CHECK_STR(str, len, _heaps, _num_heaps)                    \
  {                                                                \
    if (str) {                                                     \
      int found = 0;                                               \
      for (int i = 0; i < _num_heaps; i++) {                       \
        if (str >= _heaps[i].start && str + len <= heaps[i].end) { \
          found = 1;                                               \
        }                                                          \
      }                                                            \
      ink_release_assert(found);                                   \
    }                                                              \
  }

// struct HdrHeapSDKHandle()
//
//   Handle to a HdrHeap.
//
//   Intended to be subclassed and contain a
//     object pointer that points into the heap
//
struct HdrHeapSDKHandle {
public:
  HdrHeapSDKHandle() {}
  ~HdrHeapSDKHandle() { clear(); }
  // clear() only deallocates chained SDK return values
  //   The underlying MBuffer is left untouched
  void clear();

  // destroy() frees the underlying MBuffer and deallocates all chained
  //    SDK return values
  void destroy();

  void set(const HdrHeapSDKHandle *from);
  const char *make_sdk_string(const char *raw_str, int raw_str_len);

  HdrHeap *m_heap = nullptr;

  // In order to prevent gratitous refcounting,
  //  automatic C++ copies are disabled!
  HdrHeapSDKHandle(const HdrHeapSDKHandle &r) = delete;
  HdrHeapSDKHandle &operator=(const HdrHeapSDKHandle &r) = delete;
};

inline void
HdrHeapSDKHandle::destroy()
{
  if (m_heap) {
    m_heap->destroy();
  }
  clear();
}

inline void
HdrHeapSDKHandle::clear()
{
  m_heap = nullptr;
}

inline void
HdrHeapSDKHandle::set(const HdrHeapSDKHandle *from)
{
  clear();
  m_heap = from->m_heap;
}

HdrStrHeap *new_HdrStrHeap(int requested_size);
inkcoreapi HdrHeap *new_HdrHeap(int size = HdrHeap::DEFAULT_SIZE);

void hdr_heap_test();
