// 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_insert_hits_id = builder.InternString("num_insert_hits");
  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));
        // TODO(b/436909492): Revisit whether this value is useful.
        add_label(num_insert_hits_id,
                  info.num_insert_hits.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
