// Copyright 2017 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 LIB_UI_SCENIC_CPP_SESSION_H_
#define LIB_UI_SCENIC_CPP_SESSION_H_

#include <fuchsia/images/cpp/fidl.h>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fit/function.h>
#include <lib/zx/event.h>
#include <utility>

namespace scenic {

// Connect to Scenic and establish a new Session, as well as an InterfaceRequest
// for a SessionListener that can be hooked up as desired.
using SessionPtrAndListenerRequest =
    std::pair<fuchsia::ui::scenic::SessionPtr,
              fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>>;
SessionPtrAndListenerRequest CreateScenicSessionPtrAndListenerRequest(
    fuchsia::ui::scenic::Scenic* scenic);

// Wraps a Scenic session.
// Maintains a queue of pending operations and assists with allocation of
// resource ids.
class Session : private fuchsia::ui::scenic::SessionListener {
 public:
  // Provides timing information about a presentation request which has
  // been applied by the scene manager.
  using PresentCallback =
      fit::function<void(fuchsia::images::PresentationInfo info)>;

  // Called when session events are received.
  using EventHandler =
      fit::function<void(std::vector<fuchsia::ui::scenic::Event>)>;

  // Wraps the provided session and session listener.
  // The listener is optional.
  explicit Session(fuchsia::ui::scenic::SessionPtr session,
                   fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>
                       session_listener = nullptr);

  // Creates a new session using the provided Scenic and binds the listener to
  // this object. The Scenic itself is not retained after construction.
  explicit Session(fuchsia::ui::scenic::Scenic* scenic);

  explicit Session(SessionPtrAndListenerRequest session_and_listener);

  Session(const Session&) = delete;
  Session& operator=(const Session&) = delete;

  // Destroys the session.
  // All resources must be released prior to destruction.
  ~Session();

  void set_error_handler(fit::function<void(zx_status_t)> closure) {
    session_.set_error_handler(std::move(closure));
  }

  // Sets a callback which is invoked when events are received.
  void set_event_handler(EventHandler event_handler) {
    event_handler_ = std::move(event_handler);
  }

  // Gets a pointer to the underlying session interface.
  fuchsia::ui::scenic::Session* session() { return session_.get(); }

  // Gets the next resource id which will be provided when |AllocResourceId| is
  // called.
  uint32_t next_resource_id() const { return next_resource_id_; }

  // Allocates a new unique resource id.
  uint32_t AllocResourceId();

  // Enqueues an operation to release a resource.
  void ReleaseResource(uint32_t resource_id);

  // Enqueues an operation.
  // The session will queue operations locally to batch submission of operations
  // until |Flush()| or |Present()| is called.
  void Enqueue(fuchsia::ui::scenic::Command command);
  void Enqueue(fuchsia::ui::gfx::Command command);
  void Enqueue(fuchsia::ui::input::Command command);

  // Registers an acquire fence to be submitted during the subsequent call to
  // |Present()|.
  void EnqueueAcquireFence(zx::event fence);

  // Registers a release fence to be submitted during the subsequent call to
  // |Present()|.
  void EnqueueReleaseFence(zx::event fence);

  // Flushes queued operations to the session.
  void Flush();

  // Presents all previously enqueued operations.
  // Implicitly flushes all queued operations to the session.
  // Invokes the callback when the scene manager applies the presentation.
  void Present(uint64_t presentation_time, PresentCallback callback);

  // Unbinds the internal SessionPtr; this allows moving this across threads.
  void Unbind();

  // Rebinds the Session interface internally; this must be called after a call
  // to Unbind().
  void Rebind();

  void SetDebugName(const std::string& debug_name);

 private:
  // |fuchsia::ui::scenic::SessionListener|
  void OnScenicError(std::string error) override;
  void OnScenicEvent(std::vector<fuchsia::ui::scenic::Event> events) override;

  fuchsia::ui::scenic::SessionPtr session_;
  // |session_handle_| is stored only when |session_| is unbound/invalid.
  fidl::InterfaceHandle<fuchsia::ui::scenic::Session> session_handle_;
  uint32_t next_resource_id_ = 1u;
  uint32_t resource_count_ = 0u;

  std::vector<fuchsia::ui::scenic::Command> commands_;
  std::vector<zx::event> acquire_fences_;
  std::vector<zx::event> release_fences_;

  EventHandler event_handler_;
  fidl::Binding<fuchsia::ui::scenic::SessionListener> session_listener_binding_;
};

}  // namespace scenic

#endif  // LIB_UI_SCENIC_CPP_SESSION_H_
