// 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_UI_SCENIC_LIB_FLATLAND_UBER_STRUCT_SYSTEM_H_
#define SRC_UI_SCENIC_LIB_FLATLAND_UBER_STRUCT_SYSTEM_H_

#include <mutex>
#include <optional>
#include <queue>
#include <unordered_map>

#include "src/ui/scenic/lib/flatland/transform_handle.h"
#include "src/ui/scenic/lib/flatland/uber_struct.h"
#include "src/ui/scenic/lib/scheduling/frame_scheduler.h"

namespace flatland {

// TODO(fxbug.dev/45932): write a bug to find a better name for this system
//
// A system for aggregating local data from Flatland instances to be consumed by the render loop.
// All functions are thread safe. The intent is for separate worker threads to own each Flatland
// instance, compute local data (such as topology vectors) in their local thread, and then commit
// those vectors to this class in a concurrent manner.
class UberStructSystem {
 public:
  UberStructSystem() = default;

  // Returns the next instance ID for this particular UberStructSystem. Instance IDs are guaranteed
  // to be unique for each caller and should be used as keys for setting UberStructs and accessing
  // UberStructs in snapshots.
  TransformHandle::InstanceId GetNextInstanceId();

  // An UberStruct that has not been published to the visible snapshot and the PresentId it is
  // associated with.
  struct PendingUberStruct {
    scheduling::PresentId present_id;
    std::unique_ptr<UberStruct> uber_struct;
  };

  // An interface for UberStructSystem clients to queue UberStructs to be published into the
  // visible snapshot.
  class UberStructQueue {
   public:
    // Queues an UberStruct for |present_id|. Each Flatland instance can queue multiple UberStructs
    // in the UberStructSystem by using different PresentIds. PresentIds must be increasing between
    // subsequent calls.
    void Push(scheduling::PresentId present_id, std::unique_ptr<UberStruct> uber_struct);

    // Pops a PendingUberStruct off of this Queue. If the queue is currently empty, returns
    // std::nullopt.
    std::optional<PendingUberStruct> Pop();

    // Returns the number of PendingUberStructs in this queue.
    size_t GetPendingSize();

   private:
    // TODO(fxbug.dev/57745): add a lock-free queue.
    // Protects access to |pending_structs_|.
    std::mutex queue_mutex_;
    std::queue<PendingUberStruct> pending_structs_;
  };

  // Allocates an UberStructQueue for |session_id| and returns a shared reference to that
  // UberStructQueue. Callers should call |RemoveSession| when the session associated with that
  // |session_id| has exited to clean up the allocated resources.
  std::shared_ptr<UberStructQueue> AllocateQueueForSession(scheduling::SessionId session_id);

  // Removes the UberStructQueue and current UberStruct associated with |session_id|. Any
  // PendingUberStructs pushed into the queue after this call will never be published to the
  // InstanceMap.
  void RemoveSession(scheduling::SessionId session_id);

  // Commits a new UberStruct to the instance map for each key/value pair in |sessions_to_update|.
  // All pending UberStructs associated with each SessionId with lower PresentIds will be
  // discarded. Returns the set of SessionIds that did not have their associated PresentId in their
  // queue, indicating the session failed to update.
  scheduling::SessionUpdater::UpdateResults UpdateSessions(
      const std::unordered_map<scheduling::SessionId, scheduling::PresentId>& sessions_to_update);

  // Snapshots the current map of UberStructs and returns the copy.
  UberStruct::InstanceMap Snapshot();

  // For pushing all pending UberStructs in tests.
  void ForceUpdateAllSessions(size_t max_updates_per_queue = 10);

  // For validating cleanup logic in tests.
  size_t GetSessionCount();

  // For getting Flatland InstanceIds in tests.
  TransformHandle::InstanceId GetLatestInstanceId() const;

 private:
  // The queue of UberStructs pending for each active session. Flatland instances push UberStructs
  // onto these queues using |UberStructQueue::Push()|. This UberStructSystem removes entries using
  // |UberStructQueue::Pop()|. Both of those operations are threadsafe, but the map itself is only
  // modified from a single thread.
  std::unordered_map<scheduling::SessionId, std::shared_ptr<UberStructQueue>>
      pending_structs_queues_;

  // The current UberStruct for each Flatland instance.
  UberStruct::InstanceMap uber_struct_map_;

  // The InstanceId most recently returned from GetNextInstanceId().
  TransformHandle::InstanceId latest_instance_id_;
};

}  // namespace flatland

#endif  // SRC_UI_SCENIC_LIB_FLATLAND_UBER_STRUCT_SYSTEM_H_
