// 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/fit/function.h>
#include <lib/zx/event.h>

#include <utility>

#include "lib/fidl/cpp/binding.h"

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)>;

  // Provide information about hits.
  using HitTestCallback =
      fit::function<void(fidl::VectorPtr<fuchsia::ui::gfx::Hit> hits)>;

  // 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(); }

  // 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);

  // Performs a hit test along the specified ray.
  void HitTest(uint32_t node_id, const float ray_origin[3],
               const float ray_direction[3], HitTestCallback callback);

  // Performs a hit test along the specified ray into the engine's first
  // compositor.
  void HitTestDeviceRay(
      const float ray_origin[3], const float ray_direction[3],
      fuchsia::ui::scenic::Session::HitTestDeviceRayCallback 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_
