// Copyright 2018 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 "garnet/public/lib/ui/base_view/cpp/v1_base_view.h"

#include <lib/component/cpp/connect.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/time/time_point.h>
#include <lib/ui/geometry/cpp/geometry_util.h>
#include <trace/event.h>

namespace scenic {

V1BaseView::V1BaseView(scenic::ViewContext context,
                       const std::string& debug_name)
    : startup_context_(context.startup_context),
      view_manager_(startup_context_->ConnectToEnvironmentService<
                    ::fuchsia::ui::viewsv1::ViewManager>()),
      view_listener_binding_(this),
      view_container_listener_binding_(this),
      incoming_services_(context.outgoing_services.Bind()),
      outgoing_services_(std::move(context.incoming_services)),
      session_(std::move(context.session_and_listener_request)),
      parent_node_(&session_) {
  FXL_DCHECK(context.view_token);

  session_.SetDebugName(debug_name);

  zx::eventpair parent_export_token;
  parent_node_.BindAsRequest(&parent_export_token);

  view_manager_->CreateView2(view_.NewRequest(), std::move(context.view_token),
                             view_listener_binding_.NewBinding(),
                             std::move(parent_export_token), debug_name);

  session_.set_event_handler(
      std::bind(&V1BaseView::HandleSessionEvents, this, std::placeholders::_1));
  parent_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask);
}

V1BaseView::~V1BaseView() = default;

fuchsia::sys::ServiceProvider* V1BaseView::GetViewServiceProvider() {
  if (!view_service_provider_)
    view_->GetServiceProvider(view_service_provider_.NewRequest());
  return view_service_provider_.get();
}

::fuchsia::ui::viewsv1::ViewContainer* V1BaseView::GetViewContainer() {
  if (!view_container_) {
    view_->GetContainer(view_container_.NewRequest());
    view_container_->SetListener(view_container_listener_binding_.NewBinding());
  }
  return view_container_.get();
}

void V1BaseView::SetReleaseHandler(
    fit::function<void(zx_status_t status)> callback) {
  view_listener_binding_.set_error_handler(std::move(callback));
}

void V1BaseView::InvalidateScene() {
  if (invalidate_pending_)
    return;

  invalidate_pending_ = true;

  // Present the scene ASAP. Pass in the last presentation time; otherwise, if
  // presentation_time argument is less than the previous time passed to
  // PresentScene, the Session will be closed.
  // (We cannot use the current time because the last requested presentation
  // time, |last_presentation_time_|, could still be in the future. This is
  // because Session.Present() returns after it _begins_ preparing the given
  // frame, not after it is presented.)
  if (!present_pending_)
    PresentScene(last_presentation_time_);
}

void V1BaseView::PresentScene(zx_time_t presentation_time) {
  FXL_DCHECK(!present_pending_);

  present_pending_ = true;

  // Keep track of the most recent presentation time we've passed to
  // Session.Present(), for use in InvalidateScene().
  last_presentation_time_ = presentation_time;

  session()->Present(presentation_time,
                     [this](fuchsia::images::PresentationInfo info) {
                       FXL_DCHECK(present_pending_);

                       zx_time_t next_presentation_time =
                           info.presentation_time + info.presentation_interval;

                       bool present_needed = false;
                       if (invalidate_pending_) {
                         invalidate_pending_ = false;
                         OnSceneInvalidated(std::move(info));
                         present_needed = true;
                       }

                       present_pending_ = false;
                       if (present_needed)
                         PresentScene(next_presentation_time);
                     });
}

void V1BaseView::HandleSessionEvents(
    std::vector<fuchsia::ui::scenic::Event> events) {
  const fuchsia::ui::gfx::Metrics* new_metrics = nullptr;
  for (size_t i = 0; i < events.size(); ++i) {
    const auto& event = events[i];
    if (event.is_gfx()) {
      const fuchsia::ui::gfx::Event& scenic_event = event.gfx();
      if (scenic_event.is_metrics() &&
          scenic_event.metrics().node_id == parent_node_.id()) {
        new_metrics = &scenic_event.metrics().metrics;
      }
    } else if (event.is_input()) {
      // Act on input event just once.
      OnInputEvent(std::move(events[i].input()));
      // Create a dummy event to safely take its place.
      fuchsia::ui::scenic::Command unhandled;
      fuchsia::ui::scenic::Event unhandled_event;
      unhandled_event.set_unhandled(std::move(unhandled));
      events[i] = std::move(unhandled_event);
    }
  }

  if (new_metrics && original_metrics_ != *new_metrics) {
    original_metrics_ = *new_metrics;
    AdjustMetricsAndPhysicalSize();
  }

  OnScenicEvent(std::move(events));
}

void V1BaseView::SetNeedSquareMetrics(bool enable) {
  if (need_square_metrics_ == enable)
    return;
  need_square_metrics_ = true;
  AdjustMetricsAndPhysicalSize();
}

void V1BaseView::AdjustMetricsAndPhysicalSize() {
  adjusted_metrics_ = original_metrics_;
  if (need_square_metrics_) {
    adjusted_metrics_.scale_x = adjusted_metrics_.scale_y =
        std::max(original_metrics_.scale_x, original_metrics_.scale_y);
  }

  physical_size_.width = logical_size_.width * adjusted_metrics_.scale_x;
  physical_size_.height = logical_size_.height * adjusted_metrics_.scale_y;

  InvalidateScene();
}

void V1BaseView::OnPropertiesChanged(
    ::fuchsia::ui::viewsv1::ViewProperties old_properties) {}

void V1BaseView::OnSceneInvalidated(
    fuchsia::images::PresentationInfo presentation_info) {}

void V1BaseView::OnScenicEvent(std::vector<fuchsia::ui::scenic::Event> events) {
}

bool V1BaseView::OnInputEvent(fuchsia::ui::input::InputEvent event) {
  return false;
}

void V1BaseView::OnChildAttached(
    uint32_t child_key, ::fuchsia::ui::viewsv1::ViewInfo child_view_info) {}

void V1BaseView::OnChildUnavailable(uint32_t child_key) {}

void V1BaseView::OnPropertiesChanged(
    ::fuchsia::ui::viewsv1::ViewProperties properties,
    OnPropertiesChangedCallback callback) {
  TRACE_DURATION("view", "OnPropertiesChanged");

  ::fuchsia::ui::viewsv1::ViewProperties old_properties =
      std::move(properties_);
  properties_ = std::move(properties);

  if (logical_size_ != properties_.view_layout->size) {
    logical_size_ = properties_.view_layout->size;
    AdjustMetricsAndPhysicalSize();
  }

  OnPropertiesChanged(std::move(old_properties));

  callback();
}

void V1BaseView::OnChildAttached(
    uint32_t child_key, ::fuchsia::ui::viewsv1::ViewInfo child_view_info,
    OnChildUnavailableCallback callback) {
  TRACE_DURATION("view", "OnChildAttached", "child_key", child_key);
  OnChildAttached(child_key, std::move(child_view_info));
  callback();
}

void V1BaseView::OnChildUnavailable(uint32_t child_key,
                                    OnChildUnavailableCallback callback) {
  TRACE_DURATION("view", "OnChildUnavailable", "child_key", child_key);
  OnChildUnavailable(child_key);
  callback();
}

}  // namespace scenic
