// 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 "sdk/lib/virtualization/scenic_wayland_dispatcher.h"

#include <fuchsia/virtualization/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/gtest/test_loop_fixture.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <lib/sys/cpp/testing/fake_component.h>
#include <lib/sys/cpp/testing/fake_launcher.h>

namespace guest {

static constexpr const char* kWaylandDispatcherUrl =
    "fuchsia-pkg://fuchsia.com/wayland_bridge#meta/wayland_bridge.cmx";

class FakeDispatcher : public fuchsia::virtualization::WaylandDispatcher,
                       public fuchsia::wayland::ViewProducer {
 public:
  FakeDispatcher() {
    component_.AddPublicService(bindings_.GetHandler(this));
    component_.AddPublicService(view_producer_bindings_.GetHandler(this));
  }

  // Register to be launched with a fake URL
  void Register(sys::testing::FakeLauncher& fake_launcher) {
    component_.Register(kWaylandDispatcherUrl, fake_launcher);
  }

  size_t BindingCount() const { return bindings_.size(); }
  size_t ConnectionCount() const { return connections_.size(); }

  // Simulates the bridge dying by clearing all state and closing any bindings.
  void Terminate() {
    bindings_.CloseAll();
    view_producer_bindings_.CloseAll();
    connections_.clear();
  }

  void SendOnNewView() {
    for (auto& binding : view_producer_bindings_.bindings()) {
      zx::channel c1, c2;
      zx::channel::create(0, &c1, &c2);
      binding->events().OnNewView2(
          fidl::InterfaceHandle<fuchsia::ui::app::ViewProvider>(std::move(c1)),
          new_view_channels_.size());
      new_view_channels_.push_back(std::move(c2));
    }
  }

  void SendOnShutdownView() {
    for (auto& binding : view_producer_bindings_.bindings()) {
      new_view_channels_.pop_back();
      binding->events().OnShutdownView(new_view_channels_.size());
    }
  }

 private:
  // |fuchsia::virtualization::WaylandDispatcher|
  void OnNewConnection(zx::channel channel) { connections_.push_back(std::move(channel)); }

  sys::testing::FakeComponent component_;
  fidl::BindingSet<fuchsia::virtualization::WaylandDispatcher> bindings_;
  fidl::BindingSet<fuchsia::wayland::ViewProducer> view_producer_bindings_;
  std::vector<zx::channel> connections_;
  std::vector<zx::channel> new_view_channels_;
};

class ScenicWaylandDispatcherTest : public gtest::TestLoopFixture {
 public:
  void SetUp() override {
    TestLoopFixture::SetUp();
    dispatcher_.reset(new ScenicWaylandDispatcher(
        provider_.context(), fit::bind_member(this, &ScenicWaylandDispatcherTest::OnNewView),
        fit::bind_member(this, &ScenicWaylandDispatcherTest::OnShutdownView)));
    provider_.service_directory_provider()->AddService(fake_launcher_.GetHandler());

    fake_dispatcher_impl_.reset(new FakeDispatcher());
    fake_dispatcher_impl_->Register(fake_launcher_);
  }

  void TearDown() override { TestLoopFixture::TearDown(); }

 protected:
  ScenicWaylandDispatcher* dispatcher() const { return dispatcher_.get(); }
  FakeDispatcher* remote_dispatcher() const { return fake_dispatcher_impl_.get(); }
  std::map<uint32_t, fidl::InterfaceHandle<fuchsia::ui::app::ViewProvider>>* views() {
    return &views_;
  }

 private:
  void OnNewView(fidl::InterfaceHandle<fuchsia::ui::app::ViewProvider> view, uint32_t id) {
    views_.insert({id, std::move(view)});
  }

  void OnShutdownView(uint32_t id) { views_.erase(id); }

  sys::testing::FakeLauncher fake_launcher_;
  std::unique_ptr<FakeDispatcher> fake_dispatcher_impl_;
  sys::testing::ComponentContextProvider provider_;
  std::unique_ptr<ScenicWaylandDispatcher> dispatcher_;
  std::map<uint32_t, fidl::InterfaceHandle<fuchsia::ui::app::ViewProvider>> views_;
};

// The |ScenicWaylandDispatcher| will simply spawn a new bridge process for each
// connection and reuse that process for subsequent connections.
//
// Test that multiple connections are sent to the same bridge component.
TEST_F(ScenicWaylandDispatcherTest, LaunchBridgeOnce) {
  zx::channel c1, c2;
  zx::channel::create(0, &c1, &c2);
  dispatcher()->OnNewConnection(std::move(c1));
  RunLoopUntilIdle();
  ASSERT_EQ(1u, remote_dispatcher()->BindingCount());
  ASSERT_EQ(1u, remote_dispatcher()->ConnectionCount());

  dispatcher()->OnNewConnection(std::move(c2));
  RunLoopUntilIdle();
  ASSERT_EQ(1u, remote_dispatcher()->BindingCount());
  ASSERT_EQ(2u, remote_dispatcher()->ConnectionCount());
}

// When the remote wayland_bridge component dies, we restart it on the next
// connection request.
TEST_F(ScenicWaylandDispatcherTest, RelaunchBridgeWhenLost) {
  zx::channel c1, c2;
  zx::channel::create(0, &c1, &c2);
  dispatcher()->OnNewConnection(std::move(c1));
  RunLoopUntilIdle();
  ASSERT_EQ(1u, remote_dispatcher()->BindingCount());
  ASSERT_EQ(1u, remote_dispatcher()->ConnectionCount());

  remote_dispatcher()->Terminate();
  RunLoopUntilIdle();
  ASSERT_EQ(0u, remote_dispatcher()->BindingCount());
  ASSERT_EQ(0u, remote_dispatcher()->ConnectionCount());

  dispatcher()->OnNewConnection(std::move(c2));
  RunLoopUntilIdle();
  ASSERT_EQ(1u, remote_dispatcher()->BindingCount());
  ASSERT_EQ(1u, remote_dispatcher()->ConnectionCount());
}

// Verify we can correctly receive new ViewProviders from the remote bridge
// process.
TEST_F(ScenicWaylandDispatcherTest, ReceiveViewEvents) {
  zx::channel c1, c2;
  zx::channel::create(0, &c1, &c2);
  dispatcher()->OnNewConnection(std::move(c1));
  RunLoopUntilIdle();
  ASSERT_EQ(1u, remote_dispatcher()->BindingCount());
  ASSERT_EQ(1u, remote_dispatcher()->ConnectionCount());
  ASSERT_EQ(0u, views()->size());

  remote_dispatcher()->SendOnNewView();
  RunLoopUntilIdle();
  ASSERT_EQ(1u, views()->size());
  // View IDs are `view count - 1` for testing.
  ASSERT_EQ(1u, views()->count(0u));

  remote_dispatcher()->SendOnShutdownView();
  RunLoopUntilIdle();
  ASSERT_EQ(0u, views()->size());
}

};  // namespace guest
