// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <xdg-shell-client-protocol.h>

#include <cstdint>

#include "ash/host/ash_window_tree_host_platform.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "cc/trees/layer_tree_host.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/wayland/test/client_util.h"
#include "components/exo/wayland/test/server_util.h"
#include "components/exo/wayland/test/shell_client_data.h"
#include "components/exo/wayland/test/wayland_server_test.h"
#include "components/exo/wayland/wayland_display_output.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/test/begin_main_frame_waiter.h"

namespace exo::wayland {

namespace {

enum TestCases {
  // Xdg Client (Laros/Crostini)
  XdgByClient,
  XdgWidgetClose,
  XdgWidgetCloseNow,
  XdgWindowDelete,
  // RemoteSehell (ARC++)
  RemoteByClient,
  RemoteWidgetClose,
  RemoteWidgetCloseNow,
  RemoteWindowDelete,
};

class ShellDestructionTest : public test::WaylandServerTest,
                             public testing::WithParamInterface<TestCases> {
 public:
  ShellDestructionTest() = default;
  ShellDestructionTest(const ShellDestructionTest&) = delete;
  ShellDestructionTest& operator=(const ShellDestructionTest&) = delete;
  ~ShellDestructionTest() override = default;

  bool IsXdgShell() {
    return GetParam() == XdgWidgetCloseNow || GetParam() == XdgWindowDelete;
  }

  bool IsWidgetCloseNow() {
    return GetParam() == XdgWidgetCloseNow ||
           GetParam() == RemoteWidgetCloseNow;
  }
  bool IsWidgetClose() {
    return GetParam() == XdgWidgetClose || GetParam() == RemoteWidgetClose;
  }
  bool IsByClient() {
    return GetParam() == XdgByClient || GetParam() == RemoteByClient;
  }
};

}  // namespace

INSTANTIATE_TEST_SUITE_P(Xdg,
                         ShellDestructionTest,
                         testing::Values(XdgByClient,
                                         XdgWidgetClose,
                                         XdgWidgetCloseNow,
                                         XdgWindowDelete));
INSTANTIATE_TEST_SUITE_P(Remote,
                         ShellDestructionTest,
                         testing::Values(RemoteByClient,
                                         RemoteWidgetClose,
                                         RemoteWidgetCloseNow,
                                         RemoteWindowDelete));

// Make sure that xdg topevel/remote surfaces can be
// destroyed via Widget::CloseNow and window deletion.
// (b/276351837)
TEST_P(ShellDestructionTest, ShellDestruction) {
  test::ResourceKey surface_key;

  PostToClientAndWait([&](test::TestClient* client) {
    ASSERT_TRUE(client->InitShmBufferFactory(256 * 256 * 4));

    auto data = std::make_unique<test::ShellClientData>(client);
    auto* data_ptr = data.get();
    client->set_data(std::move(data));
    if (IsXdgShell()) {
      data_ptr->CreateXdgToplevel();
    } else {
      data_ptr->CreateRemoteSurface();
    }
    data_ptr->CreateAndAttachBuffer({256, 256});
    data_ptr->Commit();
    surface_key = data_ptr->GetSurfaceResourceKey();
  });

  Surface* surface = test::server_util::GetUserDataForResource<Surface>(
      server_.get(), surface_key);
  auto* shell_surface =
      GetShellSurfaceBaseForWindow(surface->window()->GetToplevelWindow());
  auto widget_weak_ptr = shell_surface->GetWidget()->GetWeakPtr();
  ASSERT_TRUE(shell_surface);
  ASSERT_TRUE(shell_surface->GetWidget()->IsVisible());

  if (IsWidgetClose()) {
    shell_surface->GetWidget()->Close();
    base::RunLoop().RunUntilIdle();
  } else if (IsWidgetCloseNow()) {
    shell_surface->GetWidget()->CloseNow();
  } else if (IsByClient()) {
    PostToClientAndWait([&](test::TestClient* client) {
      auto* data_ptr = client->GetDataAs<test::ShellClientData>();
      data_ptr->Close();
    });
  } else {
    delete shell_surface->GetWidget()->GetNativeWindow();
  }

  PostToClientAndWait([&](test::TestClient* client) {
    EXPECT_TRUE(client->GetDataAs<test::ShellClientData>()->close_called());
  });

  // Widget should be deleted.
  EXPECT_FALSE(widget_weak_ptr);
  // The surface resource should also be destroyed.
  EXPECT_FALSE(test::server_util::GetUserDataForResource<Surface>(server_.get(),
                                                                  surface_key));
}

using ShellWithClientTest = test::WaylandServerTest;

// Calling SetPined w/o commit should not crash (crbug.com/979128).
TEST_F(ShellWithClientTest, DestroyRootSurfaceBeforeCommit) {
  test::ResourceKey surface_key;
  PostToClientAndWait([&](test::TestClient* client) {
    ASSERT_TRUE(client->InitShmBufferFactory(256 * 256 * 4));

    auto data = std::make_unique<test::ShellClientData>(client);
    auto* data_ptr = data.get();
    client->set_data(std::move(data));
    data_ptr->CreateRemoteSurface();
    data_ptr->CreateAndAttachBuffer({256, 256});
    surface_key = data_ptr->GetSurfaceResourceKey();
  });
  EXPECT_TRUE(test::server_util::GetUserDataForResource<Surface>(server_.get(),
                                                                 surface_key));
  PostToClientAndWait([&](test::TestClient* client) {
    auto* data_ptr = client->GetDataAs<test::ShellClientData>();
    data_ptr->Pin();
    data_ptr->DestroySurface();
  });
  EXPECT_FALSE(test::server_util::GetUserDataForResource<Surface>(server_.get(),
                                                                  surface_key));
}

// Tests UnsetSnap() w/o attaching buffer doesn't crash (b/278147793).
TEST_F(ShellWithClientTest, UnsetSnapBeforeCommit) {
  test::ResourceKey surface_key;

  PostToClientAndWait([&](test::TestClient* client) {
    auto data = std::make_unique<test::ShellClientData>(client);
    auto* data_ptr = data.get();
    client->set_data(std::move(data));
    data_ptr->CreateXdgToplevel();
    surface_key = data_ptr->GetSurfaceResourceKey();
  });
  EXPECT_TRUE(test::server_util::GetUserDataForResource<Surface>(server_.get(),
                                                                 surface_key));
  // Verify the widget is not created yet.
  Surface* surface = test::server_util::GetUserDataForResource<Surface>(
      server_.get(), surface_key);
  ShellSurfaceBase* shell_surface_base =
      static_cast<ShellSurfaceBase*>(surface->GetDelegateForTesting());
  ASSERT_TRUE(shell_surface_base);
  EXPECT_FALSE(shell_surface_base->GetWidget());
  PostToClientAndWait([&](test::TestClient* client) {
    auto* data_ptr = client->GetDataAs<test::ShellClientData>();
    data_ptr->UnsetSnap();
  });
  EXPECT_TRUE(test::server_util::GetUserDataForResource<Surface>(server_.get(),
                                                                 surface_key));
}

TEST_F(ShellWithClientTest, CreateWithDisplayId) {
  UpdateDisplay("800x600, 800x600");

  auto primary_id = GetPrimaryDisplay().id();
  auto secondary_id = GetSecondaryDisplay().id();

  // Initialize client.
  PostToClientAndWait([&](test::TestClient* client) {
    ASSERT_TRUE(client->InitShmBufferFactory(800 * 100 * 4));
    ASSERT_EQ(client->globals().outputs.size(), 2u);
  });

  auto create_new_window = [this](const gfx::Rect& bounds, int output_index) {
    test::ResourceKey surface_key;
    PostToClientAndWait([&](test::TestClient* client) {
      auto data = std::make_unique<test::ShellClientData>(client);
      auto* data_ptr = data.get();
      client->set_data(std::move(data));
      data_ptr->CreateXdgToplevel();
      wl_output* target_output =
          output_index == -1 ? nullptr
                             : client->globals().outputs[output_index].get();
      data_ptr->RequestWindowBounds(bounds, target_output);
      data_ptr->Commit();
      surface_key = data_ptr->GetSurfaceResourceKey();
    });

    EXPECT_TRUE(test::server_util::GetUserDataForResource<Surface>(
        server_.get(), surface_key));
    // Verify the widget is not created yet.
    Surface* surface = test::server_util::GetUserDataForResource<Surface>(
        server_.get(), surface_key);
    ShellSurfaceBase* shell_surface_base =
        static_cast<ShellSurfaceBase*>(surface->GetDelegateForTesting());
    return shell_surface_base;
  };

  auto* screen = display::Screen::Get();
  constexpr gfx::Rect kPrimarilyOnPrimary{100, 0, 800, 100};
  {
    auto* shell_surface_base = create_new_window(kPrimarilyOnPrimary, 1);
    EXPECT_EQ(secondary_id,
              screen
                  ->GetDisplayNearestWindow(
                      shell_surface_base->GetWidget()->GetNativeWindow())
                  .id());
    EXPECT_EQ(kPrimarilyOnPrimary,
              shell_surface_base->GetWidget()->GetWindowBoundsInScreen());
  }
  {
    auto* shell_surface_base = create_new_window(kPrimarilyOnPrimary, 0);
    EXPECT_EQ(primary_id,
              screen
                  ->GetDisplayNearestWindow(
                      shell_surface_base->GetWidget()->GetNativeWindow())
                  .id());
    EXPECT_EQ(kPrimarilyOnPrimary,
              shell_surface_base->GetWidget()->GetWindowBoundsInScreen());
  }
  {
    auto* shell_surface_base = create_new_window(kPrimarilyOnPrimary, -1);
    EXPECT_EQ(primary_id,
              screen
                  ->GetDisplayNearestWindow(
                      shell_surface_base->GetWidget()->GetNativeWindow())
                  .id());
    // If display is not specified, new window will be placed fully inside the
    // display.
    // TODO(crbug.com/40212799): This logic is not consistent with
    // ash. This has to be updated once the bug is fixed.
    EXPECT_EQ(gfx::Rect{kPrimarilyOnPrimary.size()},
              shell_surface_base->GetWidget()->GetWindowBoundsInScreen());
  }

  constexpr gfx::Rect kAlmostOnPrimary{101, 0, 700, 100};
  {
    auto* shell_surface_base = create_new_window(kAlmostOnPrimary, 1);
    // The window should stay on the secondary display (output_index=1).
    EXPECT_EQ(secondary_id,
              screen
                  ->GetDisplayNearestWindow(
                      shell_surface_base->GetWidget()->GetNativeWindow())
                  .id());
    EXPECT_EQ(kAlmostOnPrimary,
              shell_surface_base->GetWidget()->GetWindowBoundsInScreen());
  }
  {
    auto* shell_surface_base = create_new_window(kAlmostOnPrimary, 0);
    EXPECT_EQ(primary_id,
              screen
                  ->GetDisplayNearestWindow(
                      shell_surface_base->GetWidget()->GetNativeWindow())
                  .id());
    EXPECT_EQ(kAlmostOnPrimary,
              shell_surface_base->GetWidget()->GetWindowBoundsInScreen());
  }
  {
    auto* shell_surface_base = create_new_window(kAlmostOnPrimary, -1);
    EXPECT_EQ(primary_id,
              screen
                  ->GetDisplayNearestWindow(
                      shell_surface_base->GetWidget()->GetNativeWindow())
                  .id());
    // TODO(crbug.com/40212799): This logic is not consistent with
    // ash. This has to be updated once the bug is fixed.
    EXPECT_EQ(gfx::Rect({100, 0}, kAlmostOnPrimary.size()),
              shell_surface_base->GetWidget()->GetWindowBoundsInScreen());
  }
}

// TODO(crbug.com/338519156): Fix and enable on MSan.
#if defined(MEMORY_SANITIZER)
#define MAYBE_BufferCommitNoNeedsCommit DISABLED_BufferCommitNoNeedsCommit
#else
#define MAYBE_BufferCommitNoNeedsCommit BufferCommitNoNeedsCommit
#endif
TEST_F(ShellWithClientTest, MAYBE_BufferCommitNoNeedsCommit) {
  auto* ash_window_tree_host = static_cast<ash::AshWindowTreeHostPlatform*>(
      ash::Shell::GetPrimaryRootWindow()->GetHost());
  // The compositor may receive draw request upon X11's damage event, which
  // results in commit request. The event is not important in this test, so
  // simply ignore the damage rect event.
  ash_window_tree_host->set_ignore_platform_damage_rect_for_test(true);
  auto* compositor = ash_window_tree_host->compositor();

  // Wait if the commit requests during initialization still exists.
  if (compositor->host_for_testing()->CommitRequested()) {
    ui::BeginMainFrameWaiter(compositor).Wait();
  }

  {
    ui::BeginMainFrameWaiter waiter(compositor);
    PostToClientAndWait([&](test::TestClient* client) {
      ASSERT_TRUE(client->InitShmBufferFactory(800 * 100 * 4));
      auto data = std::make_unique<test::ShellClientData>(client);
      auto* data_ptr = data.get();
      client->set_data(std::move(data));
      data_ptr->CreateXdgToplevel();
    });

    // Make sure a commit never been received nor processed.
    EXPECT_FALSE(waiter.begin_main_frame_received());
    EXPECT_FALSE(compositor->host_for_testing()->CommitRequested());
  }
  {
    ui::BeginMainFrameWaiter waiter(compositor);
    PostToClientAndWait([&](test::TestClient* client) {
      auto* data_ptr = client->GetDataAs<test::ShellClientData>();
      data_ptr->CreateAndAttachBuffer({256, 256});
      data_ptr->Commit();
    });
    // BeginMainFrame might have been already processed so check both
    // condition.
    EXPECT_TRUE(waiter.begin_main_frame_received() ||
                compositor->host_for_testing()->CommitRequested());
  }

  if (compositor->host_for_testing()->CommitRequested()) {
    ui::BeginMainFrameWaiter(compositor).Wait();
  }

  {
    ui::BeginMainFrameWaiter waiter(compositor);
    PostToClientAndWait([&](test::TestClient* client) {
      auto* data_ptr = client->GetDataAs<test::ShellClientData>();
      data_ptr->CreateAndAttachBuffer({256, 256});
      data_ptr->Commit();
    });
    EXPECT_FALSE(waiter.begin_main_frame_received());
    EXPECT_FALSE(compositor->host_for_testing()->CommitRequested());
  }

  {
    ui::BeginMainFrameWaiter waiter(compositor);
    PostToClientAndWait([&](test::TestClient* client) {
      auto* data_ptr = client->GetDataAs<test::ShellClientData>();
      data_ptr->CreateAndAttachBuffer({256, 128});
      data_ptr->Commit();
    });
    EXPECT_TRUE(waiter.begin_main_frame_received() ||
                compositor->host_for_testing()->CommitRequested());
  }
}

}  // namespace exo::wayland
