// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "protected_ranges.h"

#include <lib/fit/defer.h>
#include <stdio.h>
#include <zircon/assert.h>

#include <string>

#include <fbl/algorithm.h>

#include "lib/zx/time.h"
#include "macros.h"
#include "utils.h"

#define DLOG_ENABLED 0
#define BACKTRACE_DLOG 0

#if DLOG_ENABLED
static bool dynamic_dlog_enabled = true;
#if BACKTRACE_DLOG
static constexpr uint32_t kBacktraceLines = 1024;
static std::string backtrace[kBacktraceLines];
static std::atomic<uint32_t> next_backtrace_line = 0;
#define DLOG(fmt, ...)                                         \
  do {                                                         \
    if (!dynamic_dlog_enabled) {                               \
      break;                                                   \
    }                                                          \
    uint32_t __line = next_backtrace_line++;                   \
    __line = __line % kBacktraceLines;                         \
    backtrace[__line] = fxl::StringPrintf(fmt, ##__VA_ARGS__); \
  } while (0)
static void DumpBacktrace() {
  // We don't worry about dumping a few empty strings if we haven't even gotten a cycle yet; just
  // for debugging.
  LOG(INFO, "################# BACKTRACE BEGIN ###################");
  uint32_t line = next_backtrace_line % kBacktraceLines;
  for (uint32_t i = 0; i < kBacktraceLines; ++i, line = (line + 1) % kBacktraceLines) {
    LOG(INFO, "%s", backtrace[line].c_str());
    zx::nanosleep(zx::deadline_after(zx::msec(20)));
  }
  LOG(INFO, "################# BACKTRACE END ###################");
}
#else
#define DLOG(fmt, ...)             \
  do {                             \
    if (!dynamic_dlog_enabled) {   \
      break;                       \
    }                              \
    LOG(INFO, fmt, ##__VA_ARGS__); \
  } while (0)
#endif
#else
#define DLOG(fmt, ...)
#endif

namespace {

using ProtectedRanges = protected_ranges::ProtectedRanges;
using Ranges = protected_ranges::ProtectedRanges::Ranges;
using Range = protected_ranges::Range;

bool IsAnyInternalOverlap(const Ranges& ranges) {
  uint64_t last_end = 0;
  for (auto& range : ranges) {
    if (last_end > range.begin()) {
      return true;
    }
    last_end = range.end();
  }
  return false;
}

// Is a covered by b?
bool IsCoveredBy(const Range& a, const Range& b) {
  return b.begin() <= a.begin() && b.end() >= a.end();
}

bool IsOverlapping(const Range& a, const Range& b) {
  if (a.end() <= b.begin()) {
    return false;
  }
  if (b.end() <= a.begin()) {
    return false;
  }
  return true;
}

// Return a - b, in the CSG sense of no negative ranges in the result.  The result.first is what's
// left over on the left, and result.second is what's left over on the right.  Either or both can
// be empty() depending on which parts of a are covered by b.
std::pair<Range, Range> SubtractRanges(const Range& a, const Range& b) {
  // Caller must ensure this.
  ZX_DEBUG_ASSERT(Range::IsOverlap(a, b));
  Range leftover_left = Range::BeginLength(a.begin(), 0);
  Range leftover_right = Range::BeginLength(a.end(), 0);
  if (b.begin() > a.begin()) {
    leftover_left = Range::BeginEnd(a.begin(), b.begin());
  }
  if (b.end() < a.end()) {
    leftover_right = Range::BeginEnd(b.end(), a.end());
  }
  return std::make_pair(std::move(leftover_left), std::move(leftover_right));
}

const Range* FindRangeToDelete(const Ranges& old_ranges, const Ranges& new_ranges) {
  // Try to find an old range which has no overlap with any new range.
  for (auto& old_range : old_ranges) {
    auto [look_start, look_end] =
        ProtectedRanges::IteratorsCoveringPotentialOverlapsOfRangeWithRanges(old_range, new_ranges);
    bool found_overlap = false;
    for (auto look = look_start; look != look_end; ++look) {
      if (Range::IsOverlap(old_range, *look)) {
        found_overlap = true;
        break;
      }
    }
    if (!found_overlap) {
      return &old_range;
    }
  }
  return nullptr;
}

const Range* FindRangeToShorten(const Ranges& old_ranges, const Ranges& new_ranges,
                                Range* shorter_range) {
  // Try to find an old range that has a portion at the beginning or a portion at the end which is
  // not overlapping any new range.  Which old range and which end of that range to pick doesn't
  // matter because the caller will process all shorten ops quickly.  If an old range can be
  // shortened at both the beginning and end, we indicate these ops separately so that
  // DoOpShortenRange() only has to deal with shortening at one end or the other, not both.  We
  // could be a little more efficient by returning a list of shorten ops to do (collected in one
  // pass), but leaving the function signature this way makes the calling code more consistent
  // across the different ops (some of which get spread out in time instead).
  for (auto& old_range : old_ranges) {
    std::optional<uint64_t> min_overlapping_range_begin;
    std::optional<uint64_t> max_overlapping_range_end;
    auto [look_start, look_end] =
        ProtectedRanges::IteratorsCoveringPotentialOverlapsOfRangeWithRanges(old_range, new_ranges);
    for (auto look = look_start; look != look_end; ++look) {
      if (!Range::IsOverlap(old_range, *look)) {
        continue;
      }
      const Range& new_range = *look;
      if (!min_overlapping_range_begin.has_value() ||
          new_range.begin() < *min_overlapping_range_begin) {
        min_overlapping_range_begin = {new_range.begin()};
      }
      if (!max_overlapping_range_end.has_value() || new_range.end() > *max_overlapping_range_end) {
        max_overlapping_range_end = {new_range.end()};
      }
    }
    ZX_DEBUG_ASSERT(!!min_overlapping_range_begin.has_value() ==
                    !!max_overlapping_range_end.has_value());
    if (min_overlapping_range_begin.has_value() &&
        *min_overlapping_range_begin > old_range.begin()) {
      *shorter_range = Range::BeginEnd(*min_overlapping_range_begin, old_range.end());
      return &old_range;
    }
    if (max_overlapping_range_end.has_value() && *max_overlapping_range_end < old_range.end()) {
      *shorter_range = Range::BeginEnd(old_range.begin(), *max_overlapping_range_end);
      return &old_range;
    }
  }
  return nullptr;
}

const Range* FindBestSplit(const Ranges& old_ranges, const Ranges& new_ranges,
                           Range* new_gap_to_stop_using) {
  // Find the largest gap in new_ranges that's completely covered by an interior portion (not
  // touching either extreme) of a range in old_ranges.
  std::optional<Range> best_gap;
  const Range* best_gap_old_range = nullptr;
  for (auto& old_range : old_ranges) {
    auto [look_start, look_end] =
        ProtectedRanges::IteratorsCoveringPotentialOverlapsOfRangeWithRanges(old_range, new_ranges);
    const Range old_interior = Range::BeginEnd(old_range.begin() + 1, old_range.end() - 1);
    std::optional<uint64_t> prev_end;
    for (auto look = look_start; look != look_end; prev_end = {look->end()}, ++look) {
      if (!prev_end.has_value()) {
        continue;
      }
      Range new_gap = Range::BeginEnd(*prev_end, look->begin());
      if (best_gap.has_value() && new_gap.length() <= best_gap->length()) {
        continue;
      }
      if (IsCoveredBy(new_gap, old_interior)) {
        ZX_DEBUG_ASSERT(!best_gap.has_value() || new_gap.length() > best_gap->length());
        best_gap.emplace(std::move(new_gap));
        best_gap_old_range = &old_range;
      }
    }
  }
  ZX_DEBUG_ASSERT(!!best_gap.has_value() == !!best_gap_old_range);
  if (!best_gap.has_value()) {
    return nullptr;
  }
  *new_gap_to_stop_using = std::move(*best_gap);
  return best_gap_old_range;
}

const Range* FindBestMerge(const Ranges& old_ranges, const Ranges& new_ranges,
                           const Range** second_range_to_merge) {
  // Find the smallest gap in old_ranges that's covered by new_ranges (which since new_ranges is
  // coalesced, will be a single range of new_ranges doing the covering).
  std::optional<uint64_t> best_gap_size;
  const Range* best_gap_left_range = nullptr;
  const Range* best_gap_right_range = nullptr;

  const Range* prev_range = nullptr;
  for (auto& old_range : old_ranges) {
    auto set_prev_range = fit::defer([&prev_range, &old_range] { prev_range = &old_range; });
    if (!prev_range) {
      continue;
    }
    const Range old_gap = Range::BeginEnd(prev_range->end(), old_range.begin());
    if (best_gap_size.has_value() && old_gap.length() >= *best_gap_size) {
      continue;
    }
    auto [look_start, look_end] =
        ProtectedRanges::IteratorsCoveringPotentialOverlapsOfRangeWithRanges(old_gap, new_ranges);
    for (auto look = look_start; look != look_end; ++look) {
      if (IsCoveredBy(old_gap, *look)) {
        ZX_DEBUG_ASSERT(!best_gap_size.has_value() || old_gap.length() < *best_gap_size);
        best_gap_size = {old_gap.length()};
        best_gap_left_range = prev_range;
        best_gap_right_range = &old_range;
      }
    }
  }
  ZX_DEBUG_ASSERT(best_gap_size.has_value() == !!best_gap_left_range);
  ZX_DEBUG_ASSERT(best_gap_size.has_value() == !!best_gap_right_range);
  if (!best_gap_size.has_value()) {
    return nullptr;
  }
  *second_range_to_merge = best_gap_right_range;
  return best_gap_left_range;
}

Range AlignRequestedRange(const Range& range, uint64_t alignment) {
  uint64_t aligned_start = fbl::round_down(range.begin(), alignment);
  uint64_t aligned_end = fbl::round_up(range.end(), alignment);
  return Range::BeginEnd(aligned_start, aligned_end);
}

}  // namespace

namespace protected_ranges {

ProtectedRanges::ProtectedRanges(ProtectedRangesControl* ranges_control, bool disable_dynamic)
    : ranges_control_(ranges_control) {
  ZX_DEBUG_ASSERT(ranges_control_);
  is_dynamic_ = ranges_control_->IsDynamic();
  if (disable_dynamic) {
    LOG(INFO, "disable_dynamic");
    is_dynamic_ = false;
  }
  if (is_dynamic_) {
    max_range_count_ = ranges_control_->MaxRangeCount();
    ZX_DEBUG_ASSERT(max_range_count_ >= 1);
    is_mod_available_ = ranges_control_->HasModProtectedRange();
    max_logical_range_count_ = is_mod_available_ ? max_range_count_ - 1 : max_range_count_ - 2;
  } else {
    max_logical_range_count_ = 1;
  }
  range_granularity_ = ranges_control_->GetRangeGranularity();
  // We allow 1 byte granularity here for testing purposes mainly.  Actual granularity is extremely
  // likely to be at least 4KiB.
  ZX_DEBUG_ASSERT(range_granularity_ >= 1);
}

ProtectedRanges::~ProtectedRanges() { ZX_ASSERT(ranges_.empty()); }

uint64_t ProtectedRanges::max_logical_ranges() { return max_logical_range_count_; }

bool ProtectedRanges::AddRange(const Range& range_param) {
  DLOG("AddRange() begin:");
  DebugDumpRangesForUnitTest(requested_ranges_, "requested_ranges_");
  DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
  DebugDumpRangesForUnitTest(ranges_, "ranges_");
  DebugDumpRangeForUnitTest(range_param, "range");

  if (!is_dynamic_ && !requested_ranges_.empty()) {
    // The AddRange() is logically successful, but no need to track anything
    // per-range after the first range, whose required_range is the entire
    // extent of the space being managed.
    return true;
  }

  const Range& range = *requested_ranges_.emplace(range_param.Clone());
  requested_bytes_ += range.length();

  // We know that requested_ranges_ has no internal overlap.
  ZX_DEBUG_ASSERT(!IsAnyInternalOverlap(requested_ranges_));
  Range new_required_range = AlignRequestedRange(range, range_granularity_);
  if (!is_dynamic_) {
    // If !is_dynamic_, we only get to add one range, which is the entire extent of the space being
    // managed.
    new_required_range = Range::BeginLength(ranges_control_->GetBase(), ranges_control_->GetSize());
  }
  const auto required_range_iter = required_ranges_.emplace(std::move(new_required_range));
  const Range& required_range = *required_range_iter;
  PropagateRequiredRangesToGoalRanges(required_range);
  if (!FixupRangesDuringAdd(required_range)) {
    // When !is_dynamic_, we won't reach here because pages were never loaned back to Zircon, so
    // the commit during fixup will work.
    ZX_DEBUG_ASSERT(is_dynamic_);
    DLOG("!FixupRangesDuringAdd()");

    requested_bytes_ -= range.length();
    requested_ranges_.erase(range);

    // Only erase one if there are multiple that match.
    auto stash_required_range = required_range.Clone();
    required_ranges_.erase(required_ranges_.find(required_range));
    PropagateRequiredRangesToGoalRanges(stash_required_range);

    DebugDumpRangesForUnitTest(requested_ranges_, "requested_ranges_");
    DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
    DebugDumpRangesForUnitTest(ranges_, "ranges_");

    return false;
  }

  // Zero the newly requested range using the TEE.  This way any protected mode devices will see
  // the new buffer as filled with zeroes, instead of whatever REE-written zeroes might end up
  // looking like post-scramble.  In testing situations we pretend as if this is allowed at
  // arbitrary granularity, but in actual use (so far) this will assert that range is aligned at
  // page boundaries (partly because that's the smallest zeroing granularity that the TEE allows, by
  // design).
  if (is_dynamic_) {
    ranges_control_->ZeroProtectedSubRange(true, range);
  }

  DLOG("AddRange() end (success):");
  DebugDumpRangesForUnitTest(requested_ranges_, "requested_ranges_");
  DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
  DebugDumpRangesForUnitTest(ranges_, "ranges_");

  return true;
}

void ProtectedRanges::DeleteRange(const Range& range) {
  DLOG("DeleteRange() begin");
  DebugDumpRangesForUnitTest(requested_ranges_, "requested_ranges_");
  DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
  DebugDumpRangesForUnitTest(ranges_, "ranges_");
  DebugDumpRangeForUnitTest(range, "range");

  if (!is_dynamic_) {
    // At this layer, delete isn't possible if !is_dynamic_.
    return;
  }

  ZX_DEBUG_ASSERT(requested_ranges_.find(range) != requested_ranges_.end());

  requested_ranges_.erase(range);
  requested_bytes_ -= range.length();

  Range required_range = AlignRequestedRange(range, range_granularity_);
  // Only erase one if there are multiple that match.
  required_ranges_.erase(required_ranges_.find(required_range));
  PropagateRequiredRangesToGoalRanges(required_range);
  FixupRangesDuringDelete(required_range);

  DLOG("DeleteRange() end");
  DebugDumpRangesForUnitTest(requested_ranges_, "requested_ranges_");
  DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
  DebugDumpRangesForUnitTest(ranges_, "ranges_");
}

bool ProtectedRanges::FixupRangesDuringAdd(const Range& new_required_range) {
  DLOG("FixupRangesDuringAdd() begin");
#if DLOG_ENABLED
  auto at_end = fit::defer([] { DLOG("FixupRangesDuringAdd() end"); });
#endif

  // The goal of this method is to fix up ranges_ just enough to put new_required_range under a
  // range in ranges_ (and in HW), so we can complete the AddRange().  In practice, we'll only see
  // allocations at or very near the bottom of protected_memory_size or adjacent or nearly adjacent
  // to the end of an existing range (the "near" and "nearly" is because of alignment requirements
  // and plumbing those to RegionAllocator, which isn't done as of this comment, but is TODO).
  // Other placements are covered by tests in terms of logical correctness, but those other
  // placements are not relevant to efficiency in practice.
  //
  // During range deletion, we immediately opportunistically delete / shorten if we can, so this
  // fixup during add will never see a case where the new_required_range is initially touching more
  // than 1 range in ranges_ at the start and 1 range in ranges_ at the end.
  //
  // Before the end of any op, we oportunistically coalesce ranges transiently in ranges_ if we can,
  // so this fixup during add can assume that ranges_ has no ranges that are touching each other.
  // In other words, a range of adjacent blocks that are protected are protected by a single range
  // in ranges_, not by multiple ranges in ranges_.
  //
  // Steps:
  //
  // If ranges_ is completely empty, we can just add new_required_range to ranges_.
  //
  // Check if new_required_range is already fully covered by ranges_.  If so, we don't need to do
  // anything more.
  //
  // If any portion of new_required_range is not covered by ranges_, try to find the up-to-one range
  // whose end we can increase to cover the not-presently-covered portion of new_required_range.
  // Before returning we'll try to coalesce in case we can reduce the number of ranges in ranges_
  // without needing to call UseRange() (handled by DoOpExtendRangeEnd()).
  //
  // If there's no range in ranges_ whose end we can increase to cover new_required_range, then
  // if ranges_ is under max_logical_range_count_, add a new range to ranges_ just for
  // new_required_range (avoiding creating any overlap) and try to coalesce before returning.
  //
  // If ranges_.size() == max_logical_range_count_, provisionally add a new range just for
  // new_required_range (1 over max_logical_range_count_), and then merge the two adjacent blocks
  // with the smallest gap between them to get back down to max_logical_range_count_ (1 or 2 over
  // max_logical_range_count_ depending on is_mod_available).  If any UseRange() fails, roll state
  // back without any more calls to UseRange(), and return false.

  if (ranges_.empty()) {
    DLOG("ranges_.empty()");
    if (!DoOpAddRange(new_required_range)) {
      return false;
    }
    return true;
  }

  const auto range_starting_after_iter = ranges_.upper_bound(
      Range::BeginLength(new_required_range.begin(), std::numeric_limits<uint64_t>::max()));
  if (range_starting_after_iter != ranges_.begin()) {
    DLOG("append to previous range");
    // There is range starting at or before new_required_range.
    auto range_starting_at_or_before_iter = range_starting_after_iter;
    --range_starting_at_or_before_iter;
    // Check if covered already.
    if (range_starting_at_or_before_iter->begin() <= new_required_range.begin() &&
        range_starting_at_or_before_iter->end() >= new_required_range.end()) {
      DLOG("but already covered");
      // already covered; no modifications needed
      return true;
    }

    // The range_starting_at_or_before_iter can be extended to cover new_required_range.  We need
    // to avoid creating overlap, so we clamp using range_starting_after_iter->begin().
    //
    // We know (see paragraphs immediately below for why) that if range_starting_after_iter->begin()
    // is before new_required_range.end(), then the former will cover the rest of the later.
    //
    // Why (1): During requested range deletion, we delete any range in ranges_ that doesn't overlap
    // with any range in coalesced_required_ranges_.  This maintains the invariant (between ops)
    // that there is never any range in ranges_ which has no overlap with any range in
    // coalesced_required_ranges_.  Stated another way, (a) each range in ranges_ must have at least
    // one granularity-sized block of overlap with coalesced_required_ranges_.  Further, because
    // requested_ranges_ has no overlap, and because required_ranges_ is granularity-aligned form of
    // requested_ranges_, and because coalesced_required_ranges_ is de-overlapped version of
    // required_ranges_, (b) the new_required_range can overlap with (pre-existing before
    // AddRange()) coalesced_required_ranges_ at most by one granularity-sized chunk at each end.
    // We know (c) new_required_range.begin() < range_starting_after_iter->begin() (also asserted
    // below).  Because (a), (b) and (c), we know that new_required_range.end() <=
    // range_starting_after_iter->end().
    //
    // Why (2): To offer one more way to see this, it may be helpful to think of this as the
    // potentially last block of range_starting_after_iter being the potentially worst-case block of
    // overlap with coalesced_required_ranges_, and that (pre-existing) block of
    // coalesced_required_ranges_ will prevent new_required_range from ending any later than
    // range_starting_after_iter->end(), because there can be only up to one block overlap between
    // new_required_range and the (before) coalesced_required_ranges_, and pushing that overlap
    // (worst-case overlapping yes) block as far to the right as possible (worst case) still isn't
    // enough because the right-most possible location is the last block of
    // range_starting_after_iter, which then still has new_required_range ending at
    // range_starting_after_iter->end() (and not ending after).
    //
    // Hopefully those two descriptions get the idea across, but if you think of a better way to
    // describe it, please suggest.
    uint64_t new_begin = range_starting_at_or_before_iter->begin();
    uint64_t new_end = new_required_range.end();
    if (range_starting_after_iter != ranges_.end()) {
      ZX_DEBUG_ASSERT(new_required_range.begin() < range_starting_after_iter->begin());
      ZX_DEBUG_ASSERT(new_end <= range_starting_after_iter->end());
      new_end = std::min(new_end, range_starting_after_iter->begin());
    }

    // Since RegionAllocator will place new ranges as close as possible to a previous allocated
    // region, the strategy of just extending the previous block is more efficient in practice than
    // it would be if ranges were added completely randomly.  In tests we cover adding random ranges
    // and we expect it to work, but efficiency of adding a range with a big gap after the previous
    // range isn't a concern since that doesn't really happen outside of tests (at least for now).
    if (!DoOpExtendRangeEnd(*range_starting_at_or_before_iter,
                            Range::BeginEnd(new_begin, new_end))) {
      DLOG("!DoOpExtendRangeEnd()");
      return false;
    }

    // We coalesce so that we can assert that ranges_ is coalesced between ops.
    TryCoalesceAdjacentRangesAt(&ranges_, new_end);

    DebugDumpRangesForUnitTest(ranges_, "ranges_");

    return true;
  }

  // We can add a range, but we need to avoid creating any overlap.  It's possible the range after
  // the new range is starting at the last block of the range being added, so in that case we add
  // a range that's one block shorter than new_required_range to avoid overlap, and the coalesce
  // within DoOpAddRange() takes care of coalescing away the non-overlapping barely-touching
  // boundary.
  uint64_t new_end = std::min(new_required_range.end(), range_starting_after_iter->begin());
  auto adjusted_range_to_add = Range::BeginEnd(new_required_range.begin(), new_end);

  // If the new_end is the same as range_starting_after_iter->begin(), that means we'll get to
  // coalesce which means we don't have to worry about potentially needing to merge some other
  // pair of adjacent (but not touching) ranges, and we don't have to worry about needing to
  // UseRange() (which can fail) for some other gap for a merge in addition to the UseRange() for
  // the DoOpAddRange().  If not the same, then we know we can roll back the AddRange by just
  // removing adjusted_range_to_add since it won't have been coalesced.  And of course we don't have
  // any coalescing happening at the beginning of the range we're adding here because there was no
  // prior range (which would have been found above and extended to cover instead of ending up
  // here).

  if (!DoOpAddRange(adjusted_range_to_add)) {
    return false;
  }

  if (ranges_.size() <= max_logical_range_count_) {
    // We covered the range and we're still under max_logical_range_count_, so we're done.
    return true;
  }
  ZX_DEBUG_ASSERT(ranges_.size() == max_logical_range_count_ + 1);

  // Now we merge a couple other ranges that are relatively close together to get back down to
  // max_logical_range_count_.  If UseRange() fails we know we can just remove adjusted_range_to_add
  // since we know we didn't coalesce above.
  ZX_DEBUG_ASSERT(ranges_.find(adjusted_range_to_add) != ranges_.end());

  const Range* merge_right_range;
  auto merge_left_range = FindBestMerge(ranges_, goal_ranges_, &merge_right_range);
  ZX_DEBUG_ASSERT(merge_left_range);
  if (!DoOpMergeRanges(*merge_left_range, *merge_right_range)) {
    // Roll back the DoOpAddRange() above.  This also does the UnUseRange().
    DoOpDelRange(adjusted_range_to_add);
    return false;
  }
  ZX_DEBUG_ASSERT(ranges_.size() == max_logical_range_count_);

  return true;
}

void ProtectedRanges::FixupRangesDuringDelete(const Range& old_required_range) {
  // Since we can only be using max_logical_range_count_ ranges by the time the delete is done,
  // there are plenty of situations where we can't UnUseRange() on any part of old_required_range
  // despite old_required_range itself no longer being required.
  //
  // Instead of trying to do fixup that's particularly specific to delete, we can run as much
  // genereral incremental optimization as we can without needing to call UseRange().
  while (!StepTowardOptimalRangesInternal(false))
    ;

  // The StepTowardOptimalRangesInternal() calls above only look at ranges_ and goal_ranges_.  It
  // can happen that goal_ranges_ has a big range overlapping multiple ranges in ranges_, if we've
  // hit the max range count.  Despite goal_ranges_ not giving us any immediate reason to delete
  // said ranges from ranges_, some of those ranges may not overlap with any ranges in
  // coalesced_required_ranges_, and we do want to delete such ranges for two reasons.
  //
  // (1) It's convenient (for benefit of FixupRangesDuringAdd()) to maintain an invariant that every
  // range in ranges_ has at least one granularity-sized chunk of overlap with
  // coalesced_required_ranges_.
  //
  // (2) By deleting such ranges, we're (possibly only temporarily) giving the pages back to Zircon,
  // which may be (slightly) useful in avoiding a few OOMs that might have otherwise just barely
  // happened. Reason (2) is not the main reason, but (2) is maybe a very minor additional reason
  // beyond reason (1) alone.
  Ranges::iterator next_range;
  for (auto range = ranges_.begin(); range != ranges_.end(); range = next_range) {
    next_range = range;
    ++next_range;
    auto [required_begin, required_end] =
        IteratorsCoveringPotentialOverlapsOfRangeWithRanges(*range, coalesced_required_ranges_);
    auto required = required_begin;
    for (; required != required_end; ++required) {
      if (IsOverlapping(*range, *required)) {
        break;
      }
    }
    if (required != required_end) {
      // overlap found; keep range
      continue;
    }
    // no overlap with coalesced_required_ranges_ found; delete range
    //
    // The granularity-sized blocks covered by this range are covered by goal_ranges_, else we would
    // have already deleted this range in StepTowardOptimalRangesInternal(false) called above.  So
    // StepTowardOptimalRangesInternal(true) called later may (if goal_ranges_ hasn't changed by
    // then) create a range that again covers these blocks.  See the longer comment above re. why we
    // delete this range for now, despite the deletion being in some sense "temporary" at least from
    // a block coverage point of view.
    DoOpDelRange(*range);
  }
}

void ProtectedRanges::DebugDumpRangeForUnitTest(const Range& range, const char* info) {
  if constexpr (!DLOG_ENABLED) {
    return;
  }
#if DLOG_ENABLED
  if (!dynamic_dlog_enabled) {
    return;
  }
#endif
  uint64_t base = ranges_control_->GetBase();
  uint64_t size = ranges_control_->GetSize();
  uint64_t granularity = ranges_control_->GetRangeGranularity();
  ZX_ASSERT(base % granularity == 0);
  ZX_ASSERT(size % granularity == 0);
  std::string line;
  for (uint64_t i = base; i < range.begin(); ++i) {
    line += '.';
  }
  for (uint64_t i = range.begin(); i < range.end(); ++i) {
    line += 'R';
  }
  for (uint64_t i = range.end(); i < base + size; ++i) {
    line += '.';
  }
  DLOG("%s - %s", line.c_str(), info);
}

void ProtectedRanges::DebugDumpRangesForUnitTest(const Ranges& ranges, const char* info) {
  if constexpr (!DLOG_ENABLED) {
    return;
  }
#if DLOG_ENABLED
  if (!dynamic_dlog_enabled) {
    return;
  }
#endif
  uint32_t range_ordinal = 0;
  uint64_t base = ranges_control_->GetBase();
  uint64_t size = ranges_control_->GetSize();
  uint64_t granularity = ranges_control_->GetRangeGranularity();
  ZX_ASSERT(base % granularity == 0);
  ZX_ASSERT(size % granularity == 0);
  uint64_t prev_end = base;
  // We're not that concerned about efficiency for this method since we never call it outside
  // debugging and unit tests.
  std::string line;
  for (auto& iter : ranges) {
    ZX_ASSERT(!iter.empty());
    if (iter.begin() < prev_end) {
      DLOG("%s", line.c_str());
      line = "";
      prev_end = 0;
    }
    for (uint64_t j = prev_end; j < iter.begin(); ++j) {
      line += '_';
    }
    for (uint64_t j = iter.begin(); j != iter.end(); ++j) {
      line += '0' + range_ordinal % 10;
    }
    prev_end = iter.end();
    ++range_ordinal;
  }
  if (size > prev_end - base) {
    for (uint64_t j = prev_end; j != base + size; ++j) {
      line += '_';
    }
  }
  ZX_ASSERT(!line.empty());
  DLOG("%s - %s", line.c_str(), info);
}

void ProtectedRanges::DebugDumpOffset(uint64_t offset, const char* info) {
  if constexpr (!DLOG_ENABLED) {
    return;
  }
#if DLOG_ENABLED
  if (!dynamic_dlog_enabled) {
    return;
  }
#endif
  uint64_t base = ranges_control_->GetBase();
  uint64_t size = ranges_control_->GetSize();
  uint64_t granularity = ranges_control_->GetRangeGranularity();
  ZX_ASSERT(base % granularity == 0);
  ZX_ASSERT(size % granularity == 0);
  std::string line;
  for (uint64_t i = base; i < offset; ++i) {
    line += '.';
  }
  line += '^';
  for (uint64_t i = offset + 1; i < base + size; ++i) {
    line += '.';
  }
  DLOG("%s - %s", line.c_str(), info);
}

void ProtectedRanges::DebugDumpBacktrace() {
#if DLOG_ENABLED && BACKTRACE_DLOG
  DumpBacktrace();
#endif
}

void ProtectedRanges::DynamicSetDlogEnabled(bool enabled) {
#if DLOG_ENABLED && BACKTRACE_DLOG
  dynamic_dlog_enabled = enabled;
#endif
}

bool ProtectedRanges::StepTowardOptimalRanges() {
  // Here we know that ranges_ won't have any internal overlap.  At other places within ops in
  // StepTowardOptimalRangesInternal(), this won't be true.
  bool result = StepTowardOptimalRangesInternal(true);
  return result;
}

bool ProtectedRanges::StepTowardOptimalRangesInternal(bool allow_use_range) {
  DLOG("StepTowardOptimalRangesInternal(%u) begin", allow_use_range);
  DebugDumpRangesForUnitTest(requested_ranges_, "requested_ranges_");
  DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
  DebugDumpRangesForUnitTest(ranges_, "ranges_");

#if DLOG_ENABLED
  auto log_when_done = fit::defer([this, allow_use_range] {
    DLOG("StepTowardOptimalRangesInternal(%u) end", allow_use_range);
    DebugDumpRangesForUnitTest(requested_ranges_, "requested_ranges_");
    DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
    DebugDumpRangesForUnitTest(ranges_, "ranges_");
  });
#endif

  // It's fine that this way of checking will result in one extra call after the previous call made
  // the last needed change.
  if (ranges_ == goal_ranges_) {
    DLOG("ranges_ == goal_ranges_");
    return true;
  }

  // We must find at least one thing we can do to get ranges_ closer to goal_ranges_ before
  // returning.
  //
  // Both ranges_ and goal_ranges_ are maintained as fully coalesced, so we need to ensure that
  // ranges_ is always coalesced before returning.
  //
  // Priority:
  //  * clean delete
  //  * clean shorten
  //  * if ranges_.size() < max_logical_range_count_
  //    * split (pick max size gap)
  //  * else
  //    * merge (pick min size gap) then split (pick max size gap)

  auto range_to_delete = FindRangeToDelete(ranges_, goal_ranges_);
  if (range_to_delete) {
    DebugDumpRangeForUnitTest(*range_to_delete, "range_to_delete");

    DoOpDelRange(*range_to_delete);
    return false;
  }

  Range shorter_range;
  auto range_to_shorten = FindRangeToShorten(ranges_, goal_ranges_, &shorter_range);
  if (range_to_shorten) {
    DebugDumpRangeForUnitTest(*range_to_shorten, "range_to_shorten");
    DebugDumpRangeForUnitTest(shorter_range, "shorter_range");

    DoOpShortenRange(*range_to_shorten, shorter_range);
    return false;
  }

  ZX_DEBUG_ASSERT(ranges_.size() <= max_logical_range_count_);

  // We know that once we're done with splits, we're also done with merges.  Intuitively this can be
  // understood by considering that if we didn't need to do a merge to achieve a split elsewhere, we
  // wouldn't have the merge as a goal in the first place.  The count of implied splits is always >=
  // the count of implied merges.
  Range new_gap_to_stop_using;
  auto range_to_split = FindBestSplit(ranges_, goal_ranges_, &new_gap_to_stop_using);
  if (range_to_split) {
    DebugDumpRangeForUnitTest(*range_to_split, "range_to_split");
    DebugDumpRangeForUnitTest(new_gap_to_stop_using, "new_gap_to_stop_using");

    // Merge first if we need to reclaim a range overall, since merge can fail so it's easier to
    // unwind if merge doesn't work.  When merge does work (now or a little while later), we'll
    // quickly also split (which won't fail) which will allow other pages to be loaned to Zircon.
    //
    // The sequence of merges and splits to get ranges_ the rest of the way to goal_ranges_ is the
    // reason we spread out calls to StepTowardOptimalRanges() using a timer, to give Zircon a
    // chance to start using the newly-loaned pages before we reclaim yet other pages for another
    // merge.
    if (ranges_.size() == max_logical_range_count_) {
      if (!allow_use_range) {
        DLOG("ranges_.size() == max_logical_range_count_ && !allow_use_range");
        // We can't do any more without calling UseRange(), so we shouldn't do any more immediately
        // (and quickly) during DeleteRange().
        return true;
      }
      const Range* second_range_to_merge;
      auto first_range_to_merge = FindBestMerge(ranges_, goal_ranges_, &second_range_to_merge);
      if (first_range_to_merge) {
        DebugDumpRangeForUnitTest(*first_range_to_merge, "first_range_to_merge");
        DebugDumpRangeForUnitTest(*second_range_to_merge, "second_range_to_merge");

        if (!DoOpMergeRanges(*first_range_to_merge, *second_range_to_merge)) {
          // We want to get called again to try this merge again fairly soon.  UseRange() failed,
          // but it should succeed in a little while.  The sooner we can succeed the UseRange(),
          // the sooner we can do a split to loan some other pages to Zircon, and the sooner we can
          // reach goal_ranges_, which overall will be loaning as many pages to Zircon as possible.
          // But unfortunately it's quite possible to get stuck with too few pages available to play
          // "slider puzzle" to get closer to goal_ranges_.
          return false;
        }
        // Now that any needed merge is done we can do a split, but the split we do won't
        // necessarily be the same split we found before, because the merge may have merged the
        // range we found before with another range, so we need to find the/a split again just in
        // case it has changed due to the merge.
        //
        // If there was a split to do before, and all we've done since then is merge, we do know
        // that there will still be at least that gap to stop using now, so at least one split to do
        // now.
        range_to_split = FindBestSplit(ranges_, goal_ranges_, &new_gap_to_stop_using);
      }
    }
    ZX_ASSERT(range_to_split);
    DoOpSplitRange(*range_to_split, new_gap_to_stop_using);
    return false;
  }

  ZX_PANIC("Failed to match any update cases; no progress made.");
  // We won't reach here, but since we haven't reached goal_ranges_, logically we'd return false if
  // we reached here, despite having made no progress.
  return false;
}

std::pair<Ranges::iterator, Ranges::iterator>
ProtectedRanges::IteratorsCoveringPotentialOverlapsOfRangeWithRanges(const Range& range,
                                                                     const Ranges& ranges) {
  // For an r in ranges to intersect with the first byte of range, the r must begin <=
  // range.begin().  We need to find the first such range which also has r.end() > range.begin(),
  // if any.
  //
  // All prior ranges will not overlap because either ranges is not allowed to have overlapping
  // ranges, or in the case of required_ranges_, there can be overlap/duplicates, but the
  // overlap/duplication is highly restricted.  The restrictions imply that any two ranges a and b
  // in required_ranges_ will satisfy (a.begin() <= b.begin()) == (a.end() <= b.end()).  This
  // restriction is asserted in protected_ranges_test.cc.
  //
  // First we get the first r in ranges with r.begin() >= range.begin().
  auto first_ge_begin = ranges.lower_bound(Range::BeginLength(range.begin(), 0));
  auto look_begin = first_ge_begin;
  // This loop isn't really adding any time complexity overall since the caller will be iterating
  // over all these ranges anyway.
  while (look_begin != ranges.begin() &&
         (look_begin == ranges.end() || look_begin->end() > range.begin())) {
    --look_begin;
  }
  // Bump look_begin forward again if it turns out that the current look_begin is entirely before
  // range, so the caller doesn't really need to look at the current look_begin.
  if (look_begin != ranges.end() && look_begin->end() <= range.begin()) {
    ++look_begin;
  }

  // For an r in ranges to intersect with the last block of range, the r must have r.begin() <
  // range.end() (in other words r.begin() <= range.end() - 1).  No r in ranges with r.begin() >=
  // range.end() can be overlapping range.  Since ranges is ordered, we can stop looking once we've
  // looked at the last r in ranges with r.begin() < range.end(), just prior to the first r in
  // ranges with r.begin() >= range.end().
  auto first_begin_ge_range_end = ranges.lower_bound(Range::BeginLength(range.end(), 0));
  auto look_end = first_begin_ge_range_end;

  return std::make_pair(look_begin, look_end);
}

void ProtectedRanges::PropagateRequiredRangesToGoalRanges(const Range& diff_range) {
  DLOG("PropagateRequiredRangesToGoalRanges() begin");
  DebugDumpRangeForUnitTest(diff_range, "diff_range");

  UpdateCoalescedRequiredRanges(diff_range);

  DebugDumpRangesForUnitTest(coalesced_required_ranges_, "coalesced_required_ranges_");

  UpdateInteriorUnusedRanges(diff_range);

  DebugDumpRangesForUnitTest(interior_unused_ranges_, "interior_unused_ranges_");
  ZX_DEBUG_ASSERT(coalesced_required_ranges_.empty() ||
                  interior_unused_ranges_.size() + 1 == coalesced_required_ranges_.size());

  BuildLargestInteriorUnusedRanges();

  DebugDumpRangesForUnitTest(largest_interior_unused_ranges_, "largest_interior_unused_ranges_");
  ZX_DEBUG_ASSERT(largest_interior_unused_ranges_.size() ==
                  std::min(max_logical_range_count_ - 1, interior_unused_ranges_.size()));

  BuildGoalRanges();

  DebugDumpRangesForUnitTest(goal_ranges_, "goal_ranges_");
  ZX_DEBUG_ASSERT(largest_interior_unused_ranges_.empty() ||
                  goal_ranges_.size() == largest_interior_unused_ranges_.size() + 1);
  ZX_DEBUG_ASSERT(goal_ranges_.size() <= max_logical_range_count_);

  DLOG("PropagateRequiredRangesToGoalRanges() end");
}

void ProtectedRanges::UpdateCoalescedRequiredRanges(const Range& diff_range) {
  ZX_DEBUG_ASSERT(!diff_range.empty());

  // Properties of required_ranges_ that help with this step:
  //   * ordered by (begin(), length()) (lexicographically)
  //   * only up to one range can be covering both of two adjacent blocks
  // Summary of steps:
  //   * subtract diff_range from coalesced_required_ranges_, in the CSG sense (no negative ranges
  //     in the result)
  //   * find look_start, look_end portion of required_ranges_ that is guaranteed to be all the
  //     ranges in required_ranges_ that overlap any part of diff_range; this relies on look_start
  //     being the longest of the ranges that have the same begin() as look_start (or it would also
  //     be fine if it were before that longest range with the same begin(), but it happens to be
  //     the longest of the ranges with the same begin() which is slightly nicer)
  //   * establish an empty "in_progress" range positioned at the start of diff_range with zero
  //     length
  //   * iterate [look_start, look_end), at each in_progress begin value finding the max end
  //     value (end clamped by diff_range.end()), and adding/appending that max-len range to
  //     in_progress, flushing any non-empty "in_progress" to coalesced_required_ranges_ when any
  //     gap is detected (including a gap at start of diff_range, or at the end of diff_range)
  //   * upon reaching diff_range.end(), flush in_progress
  //   * call common code to try coalesce at diff_range.begin() and at diff_range.end() in case
  //     there's a range in coalesced_required_ranges_ that is barely touching a newly-built range
  //     within diff_range
  //   * done

  auto [subtract_begin, subtract_end] =
      IteratorsCoveringPotentialOverlapsOfRangeWithRanges(diff_range, coalesced_required_ranges_);
  Ranges::iterator next;
  for (auto iter = subtract_begin; iter != subtract_end; iter = next) {
    next = iter;
    ++next;
    auto& existing_range = *iter;
    if (!Range::IsOverlap(existing_range, diff_range)) {
      continue;
    }
    auto [leftover_left, leftover_right] = SubtractRanges(existing_range, diff_range);
    coalesced_required_ranges_.erase(existing_range);
    if (!leftover_left.empty()) {
      coalesced_required_ranges_.emplace(std::move(leftover_left));
    }
    if (!leftover_right.empty()) {
      coalesced_required_ranges_.emplace(std::move(leftover_right));
    }
  }

  auto [scan_begin, scan_end] =
      IteratorsCoveringPotentialOverlapsOfRangeWithRanges(diff_range, required_ranges_);
  Range in_progress = Range::BeginLength(diff_range.begin(), 0);
  auto flush_in_progress = [this, &in_progress, &diff_range](uint64_t gap_end) {
    ZX_DEBUG_ASSERT(gap_end > in_progress.end() || gap_end == diff_range.end());
    // flush in_progress and logically skip gap
    if (!in_progress.empty()) {
      coalesced_required_ranges_.emplace(std::move(in_progress));
    }
    in_progress = Range::BeginLength(gap_end, 0);
  };
  for (auto iter = scan_begin; iter != scan_end; ++iter) {
    if (iter->begin() > in_progress.end()) {
      flush_in_progress(iter->begin());
    }
    ZX_DEBUG_ASSERT(iter->begin() < diff_range.end());
    ZX_DEBUG_ASSERT(iter->begin() <= in_progress.end());
    if (iter->end() <= in_progress.end()) {
      continue;
    }
    ZX_DEBUG_ASSERT(iter->end() > in_progress.end());
    uint64_t new_end = std::min(diff_range.end(), iter->end());
    in_progress = Range::BeginEnd(in_progress.begin(), new_end);
  }
  flush_in_progress(diff_range.end());

  TryCoalesceAdjacentRangesAt(&coalesced_required_ranges_, diff_range.begin());
  TryCoalesceAdjacentRangesAt(&coalesced_required_ranges_, diff_range.end());
}

void ProtectedRanges::UpdateInteriorUnusedRanges(const Range& diff_range) {
  DLOG("UpdateInteriorUnusedRanges() begin");
#if DLOG_ENABLED
  auto before_return = fit::defer([] { DLOG("UpdateInteriorUnusedRanges() end"); });
#endif

  // The interior unused ranges are the gaps in coalesced_required_ranges_, where a "gap" is all the
  // contiguous non-covered pages that have a range of coalesced_required_ranges_ on either side.
  // The addresses before the first coalesced_required_ranges_ range's begin(), or after the last
  // range's end(), are not considered "gaps" in this context (are not interior unused ranges).
  if (coalesced_required_ranges_.size() < 2) {
    // To have an interior range we'd need there to be any interior.
    interior_unused_ranges_.clear();
    interior_unused_ranges_by_length_.clear();
    return;
  }

  // The diff_range is the required_range that was potentially changed in
  // coalesced_required_ranges_.  Due to overlaps in required_ranges_, not all parts of diff_range
  // necessarily changed, and there are situations where none of diff_range changed.
  //
  // Our strategy is to replace a part of interior_unused_ranges_.  We remove that part and
  // re-build that part, expanding enough to account for the interior_unused_ranges_ being the
  // invert of coalesced_required_ranges_.  Expanding also picks up on a newly-added range creating
  // a newly-interior unused range, and picks up on a newly-deleted range allowing two adjacent
  // unused ranges to be merged or causing a previously-interior unused range to become no longer
  // interior.
  //
  // To delete and re-build enough of interior_unused_ranges_, we're looking for the last range in
  // coalesced_required_ranges_ that has end() < diff_range.begin(), and we're looking for the first
  // range in coalesced_required_ranges_ that has begin() > diff_range.end().  In some call paths,
  // it's possible that the changes to diff_range interact with that much extra space on one side or
  // the other or both (we count merging or splitting two ranges in unused_interior_ranges_ as
  // "interacting" with those ranges).

  DebugDumpRangeForUnitTest(diff_range, "diff_range");
  DebugDumpRangesForUnitTest(coalesced_required_ranges_, "coalesced_required_ranges_");
  DebugDumpRangesForUnitTest(interior_unused_ranges_, "interior_unused_ranges_");

  auto [rebuild_begin, rebuild_end] =
      IteratorsCoveringPotentialOverlapsOfRangeWithRanges(diff_range, coalesced_required_ranges_);
  // expand rebuild_begin to include the range before any gap overlapping with diff_range
  if (rebuild_begin != coalesced_required_ranges_.begin() &&
      (rebuild_begin == coalesced_required_ranges_.end() ||
       rebuild_begin->end() > diff_range.begin())) {
    --rebuild_begin;
  }
  ZX_DEBUG_ASSERT(rebuild_begin == coalesced_required_ranges_.begin() ||
                  rebuild_begin->end() <= diff_range.begin());
  std::optional<uint64_t> maybe_carve_begin;
  if (rebuild_begin == coalesced_required_ranges_.begin()) {
    maybe_carve_begin = {};
    DLOG("maybe_carve_begin: {}");
  } else {
    maybe_carve_begin = {rebuild_begin->end()};
    DebugDumpOffset(*maybe_carve_begin, "maybe_carve_begin");
  }
  // expand rebuild_end; below we want to iterate up to and including the first range in
  // coalesced_required_ranges_ with begin() >= diff_range.end() (include the range after any gap
  // that overlaps with diff_range), so we need to bump rebuild_end later by one range.
  ZX_DEBUG_ASSERT(rebuild_end == coalesced_required_ranges_.end() ||
                  rebuild_end->begin() >= diff_range.end());
  std::optional<uint64_t> maybe_carve_end;
  if (rebuild_end == coalesced_required_ranges_.end()) {
    maybe_carve_end = {};
    DLOG("maybe_carve_end: {}");
  } else {
    maybe_carve_end = {rebuild_end->begin()};
    DebugDumpOffset(*maybe_carve_end, "maybe_carve_end");
  }
  if (rebuild_end != coalesced_required_ranges_.end()) {
    ++rebuild_end;
  }

  // Now we find which ranges of interior_unused_ranges_ are completely covered by
  // [rebuild.begin.end(), (rebuild_end - 1).begin())
  if (!interior_unused_ranges_.empty()) {
    uint64_t carve_begin;
    uint64_t carve_end;
    if (maybe_carve_begin.has_value()) {
      carve_begin = *maybe_carve_begin;
    } else {
      carve_begin = interior_unused_ranges_.begin()->begin();
    }
    DebugDumpOffset(carve_begin, "carve_begin");
    if (maybe_carve_end.has_value()) {
      carve_end = *maybe_carve_end;
    } else {
      carve_end = interior_unused_ranges_.rbegin()->end();
    }
    DebugDumpOffset(carve_end, "carve_end");
    if (carve_begin < carve_end) {
      const Range carve_range = Range::BeginEnd(carve_begin, carve_end);
      DebugDumpRangeForUnitTest(carve_range, "carve_range");
      auto [carve_begin_iter, carve_end_iter] =
          IteratorsCoveringPotentialOverlapsOfRangeWithRanges(carve_range, interior_unused_ranges_);
      Ranges::iterator next;
      for (auto iter = carve_begin_iter; iter != carve_end_iter; iter = next) {
        next = iter;
        ++next;
        DebugDumpRangeForUnitTest(*iter, "*iter");
        ZX_DEBUG_ASSERT(IsCoveredBy(*iter, carve_range));
        interior_unused_ranges_by_length_.erase(*iter);
        interior_unused_ranges_.erase(iter);
      }
    }
  }

  // Now we can find the gaps implied by [rebuild_begin, rebuild_end) and put those in
  // interior_unused_ranges_.
  std::optional<uint64_t> prev_end;
  for (auto iter = rebuild_begin; iter != rebuild_end; prev_end = {iter->end()}, ++iter) {
    if (!prev_end.has_value()) {
      continue;
    }
    auto gap_range = Range::BeginEnd(*prev_end, iter->begin());
    interior_unused_ranges_.emplace(gap_range.Clone());
    interior_unused_ranges_by_length_.emplace(std::move(gap_range));
  }

  // No need to coalesce since we expanded enough to find complete ranges in interior_unused_ranges_
  // that we remove in their entirety and then we add ranges that won't be touching each other or
  // the untouched range prior or subsequent.
}

void ProtectedRanges::BuildLargestInteriorUnusedRanges() {
  // The largest_interior_unused_ranges_ are the top (up to) max_logical_ranges_count_ - 1 ranges
  // from interior_unused_ranges_by_length_, sorted by position instead of by length.
  //
  // Since largest_interior_unused_ranges_.size() is limited by max_logical_ranges_count_ - 1,
  // there's not much reason to bother doing the update incrementally.  Instead we can just toss the
  // current ranges and re-build.  If we needed to do this incrementally it'd pretty much boil down
  // to just using the last part of interior_unused_ranges_by_length_ instead of having separate
  // Ranges for this, but at least for now it's nice to have this explicitly separate for debug and
  // test.

  largest_interior_unused_ranges_.clear();
  uint64_t ranges_to_use =
      std::min(max_logical_range_count_ - 1, interior_unused_ranges_by_length_.size());
  uint64_t range_count = 0;
  for (auto iter = interior_unused_ranges_by_length_.rbegin(); range_count != ranges_to_use;
       ++range_count, ++iter) {
    largest_interior_unused_ranges_.emplace((*iter).Clone());
  }
}

void ProtectedRanges::BuildGoalRanges() {
  // goal_ranges_ are the up to max_logical_ranges_count_ - 2 gaps in
  // largest_interior_unused_ranges_ plus a range at the start and end that covers the first+ and
  // last- blocks in coalesced_required_ranges_ without covering any blocks in
  // largest_interior_unused_ranges_.

  goal_ranges_.clear();
  // Peel off the cases that are so degenerate that they would just create more conditionals (or
  // more min()/max()) to account for them further down if we didn't peel them off here.
  if (coalesced_required_ranges_.empty()) {
    return;
  } else if (coalesced_required_ranges_.size() == 1) {
    goal_ranges_.emplace((*coalesced_required_ranges_.begin()).Clone());
    return;
  }

  // At this point we know we have at least one interior unused range, but unless we have two, we
  // won't actually find any gaps.  May as well let the loop find out there are no gaps rather than
  // checking separately.
  ZX_DEBUG_ASSERT(coalesced_required_ranges_.size() >= 2);
  // If just 1 range, the loop body will run only once and never build any gap_range(s).
  ZX_DEBUG_ASSERT(largest_interior_unused_ranges_.size() >= 1);
  std::optional<uint64_t> prev_end;
  for (auto iter = largest_interior_unused_ranges_.begin();
       iter != largest_interior_unused_ranges_.end(); prev_end = iter->end(), ++iter) {
    if (!prev_end.has_value()) {
      continue;
    }
    // The gap_range in interior unused ranges is covering some used blocks, and possibly also some
    // un-used blocks that we need to cover just to keep the number of protection ranges within HW
    // limits.
    auto gap_range = Range::BeginEnd(*prev_end, iter->begin());
    goal_ranges_.emplace(std::move(gap_range));
  }

  // There may be gaps in coalesced_required_ranges_ that are being covered by these ranges, but
  // those gaps were not among the largest gaps, so we do intentionally want to cover them.
  auto left_range = Range::BeginEnd(coalesced_required_ranges_.begin()->begin(),
                                    largest_interior_unused_ranges_.begin()->begin());
  auto right_range = Range::BeginEnd(largest_interior_unused_ranges_.rbegin()->end(),
                                     coalesced_required_ranges_.rbegin()->end());
  goal_ranges_.emplace(std::move(left_range));
  goal_ranges_.emplace(std::move(right_range));
}

bool ProtectedRanges::DoOpAddRange(const Range& new_range_param) {
  auto new_range = new_range_param.Clone();
  if (!ranges_control_->UseRange(new_range)) {
    return false;
  }
  ranges_control_->AddProtectedRange(new_range);

  ranges_.emplace(std::move(new_range));
  ranges_bytes_ += new_range_param.length();

  TryCoalesceAdjacentRangesAt(&ranges_, new_range_param.begin());
  TryCoalesceAdjacentRangesAt(&ranges_, new_range_param.end());
  return true;
}

void ProtectedRanges::DoOpDelRange(const Range& old_range) {
  ZX_DEBUG_ASSERT(ranges_.find(old_range) != ranges_.end());
  ranges_control_->DelProtectedRange(old_range);

  ranges_bytes_ -= old_range.length();
  auto stash_old_range = old_range.Clone();
  ranges_.erase(old_range);

  ranges_control_->UnUseRange(stash_old_range);

  // No need to call TryCoalesceAdjacentRangesAt(ranges_, ...) here since this is a delete.
}

void ProtectedRanges::DoOpShortenRange(const Range& old_range, const Range& new_range_param) {
  // The caller can ask for a shorten where new_range is still in active use (ongoing protected DMA
  // to/from new_range), and it's this method's job to accomplish the shorten without disrupting any
  // DMA to/from new_range.
  //
  // This method must ensure that the calls made to ranges_control_ must not cause the TEE to need
  // to zero any part of any range that overlaps new_range, since the TEE would be allowed to
  // disrupt ongoing DMA to/from that overlapping portion of new_range, which we don't want.
  //
  // We avoid disrupting ongoing DMA to/from new_range by creating a temp_range which covers the
  // portion of old_range that's going away, so that we can delay any zeroing by the TEE until the
  // last ranges_control_ step below, at which point there's no longer any other range overlapping
  // temp_range, so only DMA to/from temp_range can be disrupted (not DMA to/from any part of
  // new_range).
  //
  // This method is only called when we already know that there isn't any ongoing DMA to/from
  // temp_range.
  Range new_range = new_range_param.Clone();
  ZX_DEBUG_ASSERT(ranges_.find(old_range) != ranges_.end());
  ZX_DEBUG_ASSERT(!old_range.empty());
  ZX_DEBUG_ASSERT(!new_range.empty());
  ZX_DEBUG_ASSERT(old_range.begin() == new_range.begin() || old_range.end() == new_range.end());
  ZX_DEBUG_ASSERT(new_range.length() < old_range.length());
  ZX_DEBUG_ASSERT(ranges_.size() <= max_logical_range_count_);
  ZX_DEBUG_ASSERT(max_range_count_ - max_logical_range_count_ >= (is_mod_available_ ? 1 : 2));

  Range temp_range;
  if (old_range.begin() == new_range.begin()) {
    temp_range = Range::BeginEnd(new_range.end(), old_range.end());
  } else {
    temp_range = Range::BeginEnd(old_range.begin(), new_range.begin());
  }
  ranges_control_->AddProtectedRange(temp_range);
  if (is_mod_available_) {
    ranges_control_->ModProtectedRange(old_range, new_range);
  } else {
    ranges_control_->AddProtectedRange(new_range);
    ranges_control_->DelProtectedRange(old_range);
  }
  ranges_control_->DelProtectedRange(temp_range);

  ranges_bytes_ -= old_range.length();
  ranges_.erase(old_range);
  ranges_bytes_ += new_range.length();
  ranges_.emplace(std::move(new_range));

  ranges_control_->UnUseRange(temp_range);
}

bool ProtectedRanges::DoOpMergeRanges(const Range& first_range, const Range& second_range) {
  ZX_DEBUG_ASSERT(!first_range.empty());
  ZX_DEBUG_ASSERT(!second_range.empty());
  // We never create two ranges in ranges_ without immediately coalescing them back to one range via
  // TryCoalesceAdjacentRangesAt(ranges_, ...), so DoOpMergeRanges() is only ever used if there's at
  // least a one block gap between first_range and second_range.
  ZX_DEBUG_ASSERT(first_range.end() < second_range.begin());
  ZX_DEBUG_ASSERT(max_range_count_ - max_logical_range_count_ >= (is_mod_available_ ? 0 : 1));

  const Range gap_going_away = Range::BeginEnd(first_range.end(), second_range.begin());
  if (!ranges_control_->UseRange(gap_going_away)) {
    return false;
  }

  Range new_range = Range::BeginEnd(first_range.begin(), second_range.end());
  if (is_mod_available_) {
    ranges_control_->ModProtectedRange(first_range, new_range);
    ranges_control_->DelProtectedRange(second_range);
  } else {
    ranges_control_->AddProtectedRange(new_range);
    ranges_control_->DelProtectedRange(first_range);
    ranges_control_->DelProtectedRange(second_range);
  }

  ranges_bytes_ -= first_range.length();
  ranges_.erase(first_range);
  ranges_bytes_ -= second_range.length();
  ranges_.erase(second_range);
  ranges_bytes_ += new_range.length();
  ranges_.emplace(std::move(new_range));

  return true;
}

void ProtectedRanges::DoOpSplitRange(const Range& range_to_split,
                                     const Range& new_gap_to_stop_using) {
  ZX_DEBUG_ASSERT(!range_to_split.empty());
  ZX_DEBUG_ASSERT(!new_gap_to_stop_using.empty());
  ZX_DEBUG_ASSERT(range_to_split.begin() < new_gap_to_stop_using.begin());
  ZX_DEBUG_ASSERT(new_gap_to_stop_using.end() < range_to_split.end());
  ZX_DEBUG_ASSERT(ranges_.size() <= max_logical_range_count_ - 1);
  ZX_DEBUG_ASSERT(max_range_count_ - max_logical_range_count_ >= (is_mod_available_ ? 1 : 2));

  Range new_left_range = Range::BeginEnd(range_to_split.begin(), new_gap_to_stop_using.begin());
  Range new_right_range = Range::BeginEnd(new_gap_to_stop_using.end(), range_to_split.end());

  ranges_control_->AddProtectedRange(new_left_range);
  ranges_control_->AddProtectedRange(new_gap_to_stop_using);
  if (is_mod_available_) {
    ranges_control_->ModProtectedRange(range_to_split, new_right_range);
  } else {
    ranges_control_->AddProtectedRange(new_right_range);
    ranges_control_->DelProtectedRange(range_to_split);
  }
  ranges_control_->DelProtectedRange(new_gap_to_stop_using);

  ranges_bytes_ -= range_to_split.length();
  ranges_.erase(range_to_split);
  ranges_bytes_ += new_left_range.length();
  ranges_.emplace(std::move(new_left_range));
  ranges_bytes_ += new_right_range.length();
  ranges_.emplace(std::move(new_right_range));

  ranges_control_->UnUseRange(new_gap_to_stop_using);
}

bool ProtectedRanges::DoOpExtendRangeEnd(const Range& old_range, const Range& new_range_param) {
  auto new_range = new_range_param.Clone();
  ZX_DEBUG_ASSERT(old_range.begin() == new_range.begin());
  ZX_DEBUG_ASSERT(new_range.end() > old_range.end());
  if (!ranges_control_->UseRange(Range::BeginEnd(old_range.end(), new_range.end()))) {
    return false;
  }
  // Since we're only extending the end of a range, we can get away with just adding the new range
  // and deleting the old range, since the deletion of the old range will not need to zero any
  // blocks, so the TEE won't need to change the old_range per-device DMA write permissions.
  //
  // Using add/del here instead of mod only uses 1 transient range which is <= 2, so no reason to
  // use mod here.
  ranges_control_->AddProtectedRange(new_range);
  ranges_control_->DelProtectedRange(old_range);

  ranges_bytes_ -= old_range.length();
  ranges_.erase(old_range);
  ranges_bytes_ += new_range.length();
  auto new_range_end = new_range.end();
  ranges_.emplace(std::move(new_range));

  TryCoalesceAdjacentRangesAt(&ranges_, new_range_end);

  return true;
}

void ProtectedRanges::TryCoalesceAdjacentRangesAt(Ranges* ranges, uint64_t location) {
  ZX_DEBUG_ASSERT(ranges);
  // Determine if we actually have two adjacent barely-touching blocks that touch at location.
  if (ranges->size() < 2) {
    return;
  }
  auto second_block_iter = ranges->lower_bound(Range::BeginLength(location, 0));
  if (second_block_iter == ranges->end()) {
    // There's no block with begin() == location, so no suitable pair of blocks to weld at location.
    return;
  }
  if (second_block_iter->begin() != location) {
    ZX_DEBUG_ASSERT(second_block_iter->begin() > location);
    // There's no block starting at exactly location, so there can be no pair of blocks
    // barely-touching at location.
    return;
  }
  if (second_block_iter == ranges->begin()) {
    // No block before second_block_iter, so no welding at location is possible.
    return;
  }
  auto first_block_iter = second_block_iter;
  --first_block_iter;
  if (first_block_iter->end() != location) {
    // There's a gap, so no welding at location is possible.
    ZX_DEBUG_ASSERT(first_block_iter->end() < location);
    return;
  }
  ZX_DEBUG_ASSERT(first_block_iter->end() == location);
  ZX_DEBUG_ASSERT(second_block_iter->begin() == location);
  Range new_range = Range::BeginEnd(first_block_iter->begin(), second_block_iter->end());
  if (ranges == &ranges_) {
    // Really do the coalesce, since ranges_ mirrors HW, so keep HW up to date.
    //
    // Welding two blocks is possible.
    //
    // Since we use this in the AddRange() path and may already be at max_logical_ranges_ + 1, we
    // need to use mod if available.
    if (is_mod_available_) {
      ranges_control_->ModProtectedRange(*first_block_iter, new_range);
      ranges_control_->DelProtectedRange(*second_block_iter);
    } else {
      ranges_control_->AddProtectedRange(new_range);
      ranges_control_->DelProtectedRange(*first_block_iter);
      ranges_control_->DelProtectedRange(*second_block_iter);
    }
  }
  ranges->erase(first_block_iter);
  ranges->erase(second_block_iter);
  ranges->emplace(std::move(new_range));
}

// un-covered pages / un-used pages
double ProtectedRanges::GetEfficiency() {
  // un-covered bytes
  uint64_t un_covered_bytes = ranges_control_->GetSize() - ranges_bytes_;

  // un-used bytes
  uint64_t un_used_bytes = ranges_control_->GetSize() - requested_bytes_;

  return safe_cast<double>(un_covered_bytes) / safe_cast<double>(un_used_bytes);
}

// un-covered pages / total pages
double ProtectedRanges::GetLoanableRatio() {
  // un-covered bytes
  uint64_t un_covered_bytes = GetLoanableBytes();

  // total bytes
  uint64_t total_bytes = ranges_control_->GetSize();

  return safe_cast<double>(un_covered_bytes) / safe_cast<double>(total_bytes);
}

uint64_t ProtectedRanges::GetLoanableBytes() { return ranges_control_->GetSize() - ranges_bytes_; }

bool Range::IsOverlap(const Range& a, const Range& b) {
  if (a.end() <= b.begin()) {
    return false;
  }
  if (b.end() <= a.begin()) {
    return false;
  }
  return true;
}

Range Range::Intersect(const Range& a, const Range& b) {
  // Caller should check if we need to intersect before calling intersect, just to avoid building
  // stuff we won't use.  Alternately we could relax this and return an arbitrary empty range.
  ZX_DEBUG_ASSERT(Range::IsOverlap(a, b));
  // This is intended to work for a ranges that may include the last block before a uint64_t wraps.
  // Note that I did not say that this won't wrap in that situation; this is meant to get the
  // correct answer by exploiting the wrapping (which isn't UB for uint64_t).
  uint64_t new_begin = std::max(a.begin(), b.begin());
  uint64_t new_last = std::min(a.end() - 1, b.end() - 1);
  uint64_t new_end = new_last + 1;
  uint64_t new_length = new_end - new_begin;
  return Range::BeginLength(new_begin, new_length);
}

}  // namespace protected_ranges
