// Copyright 2025 The Abseil Authors
//
// Licensed 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
//
//     https://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.

#include "absl/profiling/hashtable.h"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/config.h"
#include "absl/container/internal/hashtablez_sampler.h"
#include "absl/profiling/internal/profile_builder.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

StatusOr<std::string> MarshalHashtableProfile() {
  return debugging_internal::MarshalHashtableProfile(
      container_internal::GlobalHashtablezSampler(), Now());
}

namespace debugging_internal {

static void DroppedHashtableSample() {}

StatusOr<std::string> MarshalHashtableProfile(
    container_internal::HashtablezSampler& sampler, Time now) {
  static constexpr absl::string_view kDropFrames =
      "(::)?absl::container_internal::.*|"
      "(::)?absl::(flat|node)_hash_(map|set).*";

  ProfileBuilder builder;
  StringId drop_frames_id = builder.InternString(kDropFrames);
  builder.set_drop_frames_id(drop_frames_id);
  builder.AddSampleType(builder.InternString("capacity"),
                        builder.InternString("count"));
  builder.set_default_sample_type_id(builder.InternString("capacity"));

  const auto capacity_id = builder.InternString("capacity");
  const auto size_id = builder.InternString("size");
  const auto num_erases_id = builder.InternString("num_erases");
  const auto num_rehashes_id = builder.InternString("num_rehashes");
  const auto max_probe_length_id = builder.InternString("max_probe_length");
  const auto total_probe_length_id = builder.InternString("total_probe_length");
  const auto stuck_bits_id = builder.InternString("stuck_bits");
  const auto inline_element_size_id =
      builder.InternString("inline_element_size");
  const auto key_size_id = builder.InternString("key_size");
  const auto value_size_id = builder.InternString("value_size");
  const auto soo_capacity_id = builder.InternString("soo_capacity");
  const auto table_age_id = builder.InternString("table_age");
  const auto max_reserve_id = builder.InternString("max_reserve");

  size_t dropped =
      sampler.Iterate([&](const container_internal::HashtablezInfo& info) {
        const size_t capacity = info.capacity.load(std::memory_order_relaxed);
        std::vector<std::pair<StringId, int64_t>> labels;

        auto add_label = [&](StringId tag, uint64_t value) {
          if (value == 0) {
            return;
          }
          labels.emplace_back(tag, static_cast<int64_t>(value));
        };

        add_label(capacity_id, capacity);
        add_label(size_id, info.size.load(std::memory_order_relaxed));
        add_label(num_erases_id,
                  info.num_erases.load(std::memory_order_relaxed));
        add_label(num_rehashes_id,
                  info.num_rehashes.load(std::memory_order_relaxed));
        add_label(max_probe_length_id,
                  info.max_probe_length.load(std::memory_order_relaxed));
        add_label(total_probe_length_id,
                  info.total_probe_length.load(std::memory_order_relaxed));
        add_label(stuck_bits_id,
                  (info.hashes_bitwise_and.load(std::memory_order_relaxed) |
                   ~info.hashes_bitwise_or.load(std::memory_order_relaxed)));
        add_label(inline_element_size_id, info.inline_element_size);
        add_label(key_size_id, info.key_size);
        add_label(value_size_id, info.value_size);
        add_label(soo_capacity_id, info.soo_capacity);
        add_label(
            table_age_id,
            static_cast<uint64_t>(ToInt64Microseconds(now - info.create_time)));
        add_label(max_reserve_id,
                  info.max_reserve.load(std::memory_order_relaxed));
        builder.AddSample(static_cast<int64_t>(capacity) * info.weight,
                          MakeSpan(info.stack, info.depth), labels);
      });

  if (dropped > 0) {
    // If we dropped samples, we don't have information for them, including
    // their sizes.  The non-zero weight allows it to be noticed in the profile
    // and examined more closely.
    //
    // We compensate for the fixup done by AddSample by adjusting the address
    // here.
    const void* kFakeStack[] = {
      absl::bit_cast<void*>(
          reinterpret_cast<uintptr_t>(&DroppedHashtableSample)+1)};
    builder.AddSample(static_cast<int64_t>(dropped), kFakeStack, {});
  }
  builder.AddCurrentMappings();
  return std::move(builder).Emit();
}

}  // namespace debugging_internal
ABSL_NAMESPACE_END
}  // namespace absl
