// Copyright 2019 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.

#ifndef SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_MEMORY_ALLOCATOR_H_
#define SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_MEMORY_ALLOCATOR_H_

#include <fidl/fuchsia.hardware.sysmem/cpp/fidl.h>
#include <fidl/fuchsia.sysmem/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <lib/fit/function.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/zx/bti.h>
#include <lib/zx/vmo.h>

#include <map>

#include "protected_ranges.h"

class SysmemMetrics;

namespace sysmem_driver {

class MemoryAllocator {
 public:
  // Some sub-classes take this interface as a constructor param, which
  // enables a fake in tests where we don't have a real zx::bti etc.
  class Owner {
   public:
    virtual inspect::Node* heap_node() = 0;
    virtual const zx::bti& bti() = 0;
    virtual zx_status_t CreatePhysicalVmo(uint64_t base, uint64_t size, zx::vmo* vmo_out) = 0;
    // Should be called after every delete that makes the allocator empty.
    virtual void CheckForUnbind() {}
    virtual SysmemMetrics& metrics() = 0;
    virtual protected_ranges::ProtectedRangesCoreControl& protected_ranges_core_control(
        const fuchsia_sysmem2::Heap& heap) {
      // Avoid requiring unrelated tests to implement.
      ZX_PANIC("protected_ranges_core_control() not implemented by subclass");
    }
    virtual bool protected_ranges_disable_dynamic() const { return false; }
    virtual void OnAllocationFailure() {}
  };

  explicit MemoryAllocator(fuchsia_hardware_sysmem::HeapProperties properties);

  virtual ~MemoryAllocator();

  // size - the needed size in bytes, rounded up to a page boundaryß
  //
  // settings - allocators may observe settings if needed, but are discouraged from looking at
  // settings unless really needed; settings.buffer_settings.size_bytes is the logical size in bytes
  // not rounded up to a page boundary, so most allocators will only care about `size` (first
  // parameter).
  //
  // name - a name that can be useful for debugging
  //
  // buffer_collection_id + buffer_index - The buffer_collection_id and buffer_index are retrievable
  // from a sysmem-provided VMO using GetVmoInfo(). Because the sysmem-provided VMO may be a child
  // (or grandchild) of the allocated VMO, the koid of parent_vmo is not generally retrievable from
  // a sysmem-provide VMO derived from parent_vmo. Allocators which don't need to correlate a
  // sysmem-provided VMO to a parent_vmo can ignore buffer_collection_id and buffer_index.
  //
  // parent_vmo - return the allocated VMO
  //
  // returns zx_status_t - the error may be useful for debugging, but the error code indicated to
  // sysmem clients will be sanitized to ZX_ERR_NO_MEMORY.
  virtual zx_status_t Allocate(uint64_t size, const fuchsia_sysmem2::SingleBufferSettings& settings,
                               std::optional<std::string> name, uint64_t buffer_collection_id,
                               uint32_t buffer_index, zx::vmo* parent_vmo) = 0;

  // This also should clean up any tracking of buffer_collection_id + buffer_index (the specific
  // combination), as zero sysmem-provided VMOs exist at this point, so it's impossible for any
  // sysmem-provided VMO to show up with the parent_vmo's buffer_collection_id + buffer_index.
  //
  // This call takes ownership of parent_vmo, and should close parent_vmo so that the memory used by
  // parent_vmo can be freed/reclaimed/recycled.
  virtual void Delete(zx::vmo parent_vmo) = 0;

  virtual zx_status_t GetPhysicalMemoryInfo(uint64_t* base, uint64_t* size) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  const fuchsia_hardware_sysmem::HeapProperties& heap_properties() const {
    return heap_properties_;
  }

  // These avoid the possibility of trying to use a sysmem-configured secure
  // heap before the TEE has told the HW to make the physical range
  // secure/protected.  The default SetReady() implementation panics, and the
  // default is_ready() just returns true.
  virtual void set_ready();
  virtual bool is_ready();

  void AddDestroyCallback(intptr_t key, fit::callback<void()> callback);
  void RemoveDestroyCallback(intptr_t key);

  // Returns true if there are no outstanding allocations, or if the allocator only allocates fully
  // independent VMOs that fully own their own memory separate from any tracking in sysmem.
  // Allocators must be empty before they're deleted.
  virtual bool is_empty() = 0;

  uint64_t id() const { return id_; }

  virtual bool is_already_cleared_on_allocate() { return false; }

 public:
  std::map<intptr_t, fit::callback<void()>> destroy_callbacks_;

 private:
  // This is a unique ID for the allocator on this system.
  uint64_t id_{};
  fuchsia_hardware_sysmem::HeapProperties heap_properties_;
};

}  // namespace sysmem_driver

#endif  // SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_MEMORY_ALLOCATOR_H_
