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

#include "src/lib/ui/base_view/base_view.h"

#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl_test_base.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>

#include <gmock/gmock.h>
#include <src/lib/fostr/fidl/fuchsia/ui/gfx/formatting.h>

#include "src/lib/testing/loop_fixture/test_loop_fixture.h"

using ::testing::_;

namespace scenic {

class MockSession : public fuchsia::ui::scenic::testing::Session_TestBase {
 public:
  MockSession() : binding_(this) {}

  void NotImplemented_(const std::string& name) final {}

  void Bind(fidl::InterfaceRequest<::fuchsia::ui::scenic::Session> request,
            ::fuchsia::ui::scenic::SessionListenerPtr listener) {
    binding_.Bind(std::move(request));
    listener_ = std::move(listener);
  }

  MOCK_METHOD(void, Present,
              (uint64_t presentation_time, std::vector<zx::event> acquire_fences,
               std::vector<zx::event> release_fences, PresentCallback callback));

 private:
  fidl::Binding<fuchsia::ui::scenic::Session> binding_;
  fuchsia::ui::scenic::SessionListenerPtr listener_;
};

class FakeScenic : public fuchsia::ui::scenic::testing::Scenic_TestBase {
 public:
  void NotImplemented_(const std::string& name) final {}

  fidl::InterfaceRequestHandler<fuchsia::ui::scenic::Scenic> GetRequestHandler() {
    return bindings_.GetHandler(this);
  }

  void CreateSession(
      fidl::InterfaceRequest<fuchsia::ui::scenic::Session> session,
      fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> listener) override {
    mock_session_.Bind(std::move(session), listener.Bind());
  }

  MockSession* mock_session() { return &mock_session_; }

 private:
  fidl::BindingSet<fuchsia::ui::scenic::Scenic> bindings_;
  MockSession mock_session_;
};

class BaseViewImpl : public BaseView {
 public:
  BaseViewImpl(ViewContext context, const std::string& debug_name)
      : BaseView(std::move(context), debug_name) {}

  void DoPresentScene() { PresentScene(); }

 private:
  // |fuchsia::ui::scenic::SessionListener|
  void OnScenicError(std::string error) override {}
};

class BaseViewTest : public gtest::TestLoopFixture {
 protected:
  void SetUp() override {
    provider.service_directory_provider()->AddService(fake_scenic_.GetRequestHandler());

    auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
    auto component_context = provider.TakeContext();

    scenic::ViewContext view_context = {
        .session_and_listener_request =
            scenic::CreateScenicSessionPtrAndListenerRequest(&fake_scenic_),
        .view_token = std::move(view_token),
        .component_context = component_context.get(),
    };
    view_holder_token_ = std::move(view_holder_token);
    component_context_ = std::move(component_context);
    base_view_ = std::make_unique<BaseViewImpl>(std::move(view_context), std::string());
  }

  std::unique_ptr<BaseViewImpl> base_view_;
  FakeScenic fake_scenic_;

 private:
  sys::testing::ComponentContextProvider provider;
  fuchsia::ui::views::ViewHolderToken view_holder_token_;
  std::unique_ptr<sys::ComponentContext> component_context_;
};

TEST_F(BaseViewTest, HandlesMultiplePresentCalls) {
  // Expect Present() calls in initialization.
  EXPECT_CALL(*fake_scenic_.mock_session(), Present(_, _, _, _))
      .WillRepeatedly([](uint64_t presentation_time, std::vector<zx::event> acquire_fences,
                         std::vector<zx::event> release_fences, Session::PresentCallback callback) {
        callback(fuchsia::images::PresentationInfo());
      });
  RunLoopUntilIdle();
  ASSERT_TRUE(testing::Mock::VerifyAndClear(fake_scenic_.mock_session()));

  // Queue 3 calls but expect only 1 to be sent to Session.
  EXPECT_CALL(*fake_scenic_.mock_session(), Present(_, _, _, _)).Times(1);
  base_view_->DoPresentScene();
  base_view_->DoPresentScene();
  base_view_->DoPresentScene();
  RunLoopUntilIdle();
}

TEST_F(BaseViewTest, InvalidateCallbackInvoked) {
  // Expect Present() calls in initialization.
  EXPECT_CALL(*fake_scenic_.mock_session(), Present(_, _, _, _))
      .WillRepeatedly([](uint64_t presentation_time, std::vector<zx::event> acquire_fences,
                         std::vector<zx::event> release_fences, Session::PresentCallback callback) {
        callback(fuchsia::images::PresentationInfo());
      });
  RunLoopUntilIdle();
  ASSERT_TRUE(testing::Mock::VerifyAndClear(fake_scenic_.mock_session()));

  size_t num_present_callbacks = 0;
  EXPECT_CALL(*fake_scenic_.mock_session(), Present(_, _, _, _))
      .Times(2)
      .WillRepeatedly([&num_present_callbacks](uint64_t presentation_time,
                                               std::vector<zx::event> acquire_fences,
                                               std::vector<zx::event> release_fences,
                                               Session::PresentCallback callback) {
        num_present_callbacks++;
        callback(fuchsia::images::PresentationInfo());
      });
  base_view_->InvalidateScene();
  base_view_->DoPresentScene();

  // Now that there's a PresentScene pending, expect that InvalidateScene() will trigger
  // a second Present, and won't receive it's callback until the second present.
  bool callback_invoked;
  base_view_->InvalidateScene([&num_present_callbacks, &callback_invoked](auto) {
    EXPECT_EQ(num_present_callbacks, 2u);
    callback_invoked = true;
  });
  RunLoopUntilIdle();
  EXPECT_TRUE(callback_invoked);
}

}  // namespace scenic
