/** @file

  Extendible

  @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.

  @section details Details

////////////////////////////////////////////
  Implements:
  * Extendible<Derived_t>
  * Schema
  * fieldAdd
  * fieldFind
 */

#include "tscore/Extendible.h"

namespace ext
{
namespace details
{
  ////////////////////////////////////////////////////
  // Schema Methods

  Schema::~Schema() {}

  void
  Schema::updateMemOffsets()
  {
    ink_release_assert(cnt_constructed == cnt_destructed);

    uint32_t acc_offset = 0;
    alloc_align         = 1;

    for (auto &pair_fld : fields) {
      alloc_align = std::max(alloc_align, pair_fld.second.align);
    }

    // allocate fields from largest to smallest alignment
    uint8_t processing_align = alloc_align;
    while (processing_align > 0) {
      uint8_t next_align = 0;
      for (auto &pair_fld : fields) {
        auto &fld = pair_fld.second;
        if (fld.align == processing_align) {
          fld.field_offset = acc_offset;
          acc_offset += fld.size;
        } else if (fld.align < processing_align) {
          next_align = std::max(next_align, fld.align);
        }
      }
      processing_align = next_align;
    }

    // align '0' are packed bit allocations.
    uint32_t acc_bit_offset = 0;
    for (auto &pair_fld : fields) {
      auto &fld = pair_fld.second;
      if (fld.align == 0) {
        fld.field_offset = acc_offset + acc_bit_offset / 8;
        fld.mask         = 1 << (acc_bit_offset % 8);
        ++acc_bit_offset;
      }
    }

    alloc_size = acc_offset + (acc_bit_offset + 7) / 8;
  }

  bool
  Schema::reset()
  {
    if (cnt_constructed > cnt_destructed) {
      // free instances before calling this so we don't leak memory
      return false;
    }
    fields.clear();
    updateMemOffsets();
    return true;
  }

  void
  Schema::callConstructor(uintptr_t ext_loc)
  {
    ink_assert(ext_loc);
    ++cnt_fld_constructed; // don't allow schema modification
    ink_assert(cnt_fld_constructed <= cnt_constructed);

    // init all extendible memory to 0, incase constructors don't
    memset(reinterpret_cast<void *>(ext_loc), 0, alloc_size);

    for (auto const &elm : fields) {
      if (elm.second.constructor) {
        elm.second.constructor(FieldPtr(ext_loc + elm.second.field_offset));
      }
    }
  }

  void
  Schema::callDestructor(uintptr_t ext_loc)
  {
    ink_assert(ext_loc);
    for (auto const &elm : fields) {
      if (elm.second.destructor) {
        elm.second.destructor(FieldPtr(ext_loc + elm.second.field_offset));
      }
    }
  }

  size_t
  Schema::fullSize(const size_t base_size) const
  {
    ink_assert(base_size);
    return ROUNDUP(base_size, alloc_align) + alloc_size;
  }

  bool
  Schema::no_instances() const
  {
    return cnt_constructed == cnt_destructed;
  }
} // namespace details

} // namespace ext
