// Copyright 2014 The Chromium 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 <string>
#include <vector>

#include "base/message_loop/message_loop.h"
#include "mojo/converters/geometry/geometry_type_converters.h"
#include "mojo/public/interfaces/application/service_provider.mojom.h"
#include "mojo/services/view_manager/public/cpp/types.h"
#include "mojo/services/view_manager/public/cpp/util.h"
#include "mojo/services/view_manager/public/interfaces/view_manager.mojom.h"
#include "mojo/services/window_manager/public/interfaces/window_manager.mojom.h"
#include "mojo/services/window_manager/public/interfaces/window_manager_internal.mojom.h"
#include "services/view_manager/client_connection.h"
#include "services/view_manager/connection_manager.h"
#include "services/view_manager/connection_manager_delegate.h"
#include "services/view_manager/display_manager.h"
#include "services/view_manager/ids.h"
#include "services/view_manager/server_view.h"
#include "services/view_manager/test_change_tracker.h"
#include "services/view_manager/view_manager_service_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"

using mojo::Array;
using mojo::ERROR_CODE_NONE;
using mojo::InterfaceRequest;
using mojo::ServiceProvider;
using mojo::ServiceProviderPtr;
using mojo::String;
using mojo::ViewDataPtr;

namespace view_manager {
namespace {

// -----------------------------------------------------------------------------

// ViewManagerClient implementation that logs all calls to a TestChangeTracker.
// TODO(sky): refactor so both this and ViewManagerServiceAppTest share code.
class TestViewManagerClient : public mojo::ViewManagerClient {
 public:
  TestViewManagerClient() {}
  ~TestViewManagerClient() override {}

  TestChangeTracker* tracker() { return &tracker_; }

 private:
  // ViewManagerClient:
  void OnEmbed(uint16_t connection_id,
               const String& embedder_url,
               ViewDataPtr root,
               mojo::ViewManagerServicePtr view_manager_service,
               InterfaceRequest<ServiceProvider> services,
               ServiceProviderPtr exposed_services,
               mojo::ScopedMessagePipeHandle window_manager_pipe) override {
    tracker_.OnEmbed(connection_id, embedder_url, root.Pass());
  }
  void OnEmbeddedAppDisconnected(uint32_t view) override {
    tracker_.OnEmbeddedAppDisconnected(view);
  }
  void OnViewBoundsChanged(uint32_t view,
                           mojo::RectPtr old_bounds,
                           mojo::RectPtr new_bounds) override {
    tracker_.OnViewBoundsChanged(view, old_bounds.Pass(), new_bounds.Pass());
  }
  void OnViewViewportMetricsChanged(
      mojo::ViewportMetricsPtr old_metrics,
      mojo::ViewportMetricsPtr new_metrics) override {
    tracker_.OnViewViewportMetricsChanged(old_metrics.Pass(),
                                          new_metrics.Pass());
  }
  void OnViewHierarchyChanged(uint32_t view,
                              uint32_t new_parent,
                              uint32_t old_parent,
                              Array<ViewDataPtr> views) override {
    tracker_.OnViewHierarchyChanged(view, new_parent, old_parent, views.Pass());
  }
  void OnViewReordered(uint32_t view_id,
                       uint32_t relative_view_id,
                       mojo::OrderDirection direction) override {
    tracker_.OnViewReordered(view_id, relative_view_id, direction);
  }
  void OnViewDeleted(uint32_t view) override { tracker_.OnViewDeleted(view); }
  void OnViewVisibilityChanged(uint32_t view, bool visible) override {
    tracker_.OnViewVisibilityChanged(view, visible);
  }
  void OnViewDrawnStateChanged(uint32_t view, bool drawn) override {
    tracker_.OnViewDrawnStateChanged(view, drawn);
  }
  void OnViewSharedPropertyChanged(uint32_t view,
                                   const String& name,
                                   Array<uint8_t> new_data) override {
    tracker_.OnViewSharedPropertyChanged(view, name, new_data.Pass());
  }
  void OnViewInputEvent(uint32_t view,
                        mojo::EventPtr event,
                        const mojo::Callback<void()>& callback) override {
    tracker_.OnViewInputEvent(view, event.Pass());
  }

  TestChangeTracker tracker_;

  DISALLOW_COPY_AND_ASSIGN(TestViewManagerClient);
};

// -----------------------------------------------------------------------------

// ClientConnection implementation that vends TestViewManagerClient.
class TestClientConnection : public ClientConnection {
 public:
  explicit TestClientConnection(scoped_ptr<ViewManagerServiceImpl> service_impl)
      : ClientConnection(service_impl.Pass(), &client_) {}
  ~TestClientConnection() override {}

  TestViewManagerClient* client() { return &client_; }

 private:
  TestViewManagerClient client_;

  DISALLOW_COPY_AND_ASSIGN(TestClientConnection);
};

// -----------------------------------------------------------------------------

// Empty implementation of ConnectionManagerDelegate.
class TestConnectionManagerDelegate : public ConnectionManagerDelegate {
 public:
  TestConnectionManagerDelegate() : last_connection_(nullptr) {}
  ~TestConnectionManagerDelegate() override {}

  TestViewManagerClient* last_client() {
    return last_connection_ ? last_connection_->client() : nullptr;
  }

  TestClientConnection* last_connection() { return last_connection_; }

 private:
  // ConnectionManagerDelegate:
  void OnLostConnectionToWindowManager() override {}

  ClientConnection* CreateClientConnectionForEmbedAtView(
      ConnectionManager* connection_manager,
      mojo::InterfaceRequest<mojo::ViewManagerService> service_request,
      mojo::ConnectionSpecificId creator_id,
      const std::string& creator_url,
      const std::string& url,
      const ViewId& root_id) override {
    scoped_ptr<ViewManagerServiceImpl> service(new ViewManagerServiceImpl(
        connection_manager, creator_id, creator_url, url, root_id));
    last_connection_ = new TestClientConnection(service.Pass());
    return last_connection_;
  }
  ClientConnection* CreateClientConnectionForEmbedAtView(
      ConnectionManager* connection_manager,
      mojo::InterfaceRequest<mojo::ViewManagerService> service_request,
      mojo::ConnectionSpecificId creator_id,
      const std::string& creator_url,
      const ViewId& root_id,
      mojo::ViewManagerClientPtr client) override {
    NOTIMPLEMENTED();
    return nullptr;
  }

  TestClientConnection* last_connection_;

  DISALLOW_COPY_AND_ASSIGN(TestConnectionManagerDelegate);
};

// -----------------------------------------------------------------------------

// Empty implementation of DisplayManager.
class TestDisplayManager : public DisplayManager {
 public:
  TestDisplayManager() {}
  ~TestDisplayManager() override {}

  // DisplayManager:
  void Init(ConnectionManager* connection_manager) override {}
  void SchedulePaint(const ServerView* view, const gfx::Rect& bounds) override {
  }
  void SetViewportSize(const gfx::Size& size) override {}
  const mojo::ViewportMetrics& GetViewportMetrics() override {
    return display_metrices_;
  }

 private:
  mojo::ViewportMetrics display_metrices_;

  DISALLOW_COPY_AND_ASSIGN(TestDisplayManager);
};

// -----------------------------------------------------------------------------

// Empty implementation of WindowManagerInternal.
class TestWindowManagerInternal : public mojo::WindowManagerInternal {
 public:
  TestWindowManagerInternal() {}
  ~TestWindowManagerInternal() override {}

  // WindowManagerInternal:
  void CreateWindowManagerForViewManagerClient(
      uint16_t connection_id,
      mojo::ScopedMessagePipeHandle window_manager_pipe) override {}
  void SetViewManagerClient(mojo::ScopedMessagePipeHandle) override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(TestWindowManagerInternal);
};

}  // namespace

// -----------------------------------------------------------------------------

class ViewManagerServiceTest : public testing::Test {
 public:
  ViewManagerServiceTest() : wm_client_(nullptr) {}
  ~ViewManagerServiceTest() override {}

  // ViewManagerServiceImpl for the window manager.
  ViewManagerServiceImpl* wm_connection() {
    return connection_manager_->GetConnection(1);
  }

  TestViewManagerClient* last_view_manager_client() {
    return delegate_.last_client();
  }

  TestClientConnection* last_client_connection() {
    return delegate_.last_connection();
  }

  ConnectionManager* connection_manager() { return connection_manager_.get(); }

  TestViewManagerClient* wm_client() { return wm_client_; }

 protected:
  // testing::Test:
  void SetUp() override {
    connection_manager_.reset(new ConnectionManager(
        &delegate_, scoped_ptr<DisplayManager>(new TestDisplayManager),
        &wm_internal_));
    scoped_ptr<ViewManagerServiceImpl> service(new ViewManagerServiceImpl(
        connection_manager_.get(), kInvalidConnectionId, std::string(),
        std::string("mojo:window_manager"), RootViewId()));
    scoped_ptr<TestClientConnection> client_connection(
        new TestClientConnection(service.Pass()));
    wm_client_ = client_connection->client();
    ASSERT_TRUE(wm_client_ != nullptr);
    connection_manager_->SetWindowManagerClientConnection(
        client_connection.Pass());
    ASSERT_TRUE(wm_connection() != nullptr);
    ASSERT_TRUE(wm_connection()->root() != nullptr);
  }

 private:
  // TestViewManagerClient that is used for the WM connection.
  TestViewManagerClient* wm_client_;

  TestWindowManagerInternal wm_internal_;
  TestConnectionManagerDelegate delegate_;
  scoped_ptr<ConnectionManager> connection_manager_;
  base::MessageLoop message_loop_;

  DISALLOW_COPY_AND_ASSIGN(ViewManagerServiceTest);
};

namespace {

const ServerView* GetFirstCloned(const ServerView* view) {
  for (const ServerView* child : view->GetChildren()) {
    if (child->id() == ClonedViewId())
      return child;
  }
  return nullptr;
}

// Provides common setup for animation tests. Creates the following views:
// 0,1 (the root, provided by view manager)
//   1,1 the second connection is embedded here (view owned by wm_connection()).
//     2,1 bounds=1,2 11x22
//       2,2 bounds=2,3 6x7
//         2,3 bounds=3,4 6x7
// CloneAndAnimate() is invoked for 2,2.
void SetUpAnimate1(ViewManagerServiceTest* test, ViewId* embed_view_id) {
  *embed_view_id = ViewId(test->wm_connection()->id(), 1);
  EXPECT_EQ(ERROR_CODE_NONE, test->wm_connection()->CreateView(*embed_view_id));
  EXPECT_TRUE(test->wm_connection()->SetViewVisibility(*embed_view_id, true));
  EXPECT_TRUE(test->wm_connection()->AddView(*(test->wm_connection()->root()),
                                             *embed_view_id));
  test->wm_connection()->EmbedUrl(std::string(), *embed_view_id, nullptr,
                                  nullptr);
  ViewManagerServiceImpl* connection1 =
      test->connection_manager()->GetConnectionWithRoot(*embed_view_id);
  ASSERT_TRUE(connection1 != nullptr);
  ASSERT_NE(connection1, test->wm_connection());

  const ViewId child1(connection1->id(), 1);
  EXPECT_EQ(ERROR_CODE_NONE, connection1->CreateView(child1));
  const ViewId child2(connection1->id(), 2);
  EXPECT_EQ(ERROR_CODE_NONE, connection1->CreateView(child2));
  const ViewId child3(connection1->id(), 3);
  EXPECT_EQ(ERROR_CODE_NONE, connection1->CreateView(child3));

  ServerView* v1 = connection1->GetView(child1);
  v1->SetVisible(true);
  v1->SetBounds(gfx::Rect(1, 2, 11, 22));
  ServerView* v2 = connection1->GetView(child2);
  v2->SetVisible(true);
  v2->SetBounds(gfx::Rect(2, 3, 6, 7));
  ServerView* v3 = connection1->GetView(child3);
  v3->SetVisible(true);
  v3->SetBounds(gfx::Rect(3, 4, 6, 7));

  EXPECT_TRUE(connection1->AddView(*embed_view_id, child1));
  EXPECT_TRUE(connection1->AddView(child1, child2));
  EXPECT_TRUE(connection1->AddView(child2, child3));

  TestViewManagerClient* connection1_client = test->last_view_manager_client();
  connection1_client->tracker()->changes()->clear();
  test->wm_client()->tracker()->changes()->clear();
  EXPECT_TRUE(test->connection_manager()->CloneAndAnimate(child2));
  EXPECT_TRUE(connection1_client->tracker()->changes()->empty());
  EXPECT_TRUE(test->wm_client()->tracker()->changes()->empty());

  // We cloned v2. The cloned view ends up as a sibling of it.
  const ServerView* cloned_view = GetFirstCloned(connection1->GetView(child1));
  ASSERT_TRUE(cloned_view);
  // |cloned_view| should have one and only one cloned child (corresponds to
  // |child3|).
  ASSERT_EQ(1u, cloned_view->GetChildren().size());
  EXPECT_TRUE(cloned_view->GetChildren()[0]->id() == ClonedViewId());

  // Cloned views should match the bounds of the view they were cloned from.
  EXPECT_EQ(v2->bounds(), cloned_view->bounds());
  EXPECT_EQ(v3->bounds(), cloned_view->GetChildren()[0]->bounds());

  // Cloned views are owned by the ConnectionManager and shouldn't be returned
  // from ViewManagerServiceImpl::GetView.
  EXPECT_TRUE(connection1->GetView(ClonedViewId()) == nullptr);
  EXPECT_TRUE(test->wm_connection()->GetView(ClonedViewId()) == nullptr);
}

}  // namespace

// Verifies ViewManagerService::GetViewTree() doesn't return cloned views.
TEST_F(ViewManagerServiceTest, ConnectionsCantSeeClonedViews) {
  ViewId embed_view_id;
  EXPECT_NO_FATAL_FAILURE(SetUpAnimate1(this, &embed_view_id));

  ViewManagerServiceImpl* connection1 =
      connection_manager()->GetConnectionWithRoot(embed_view_id);

  const ViewId child1(connection1->id(), 1);
  const ViewId child2(connection1->id(), 2);
  const ViewId child3(connection1->id(), 3);

  // Verify the root doesn't see any cloned views.
  std::vector<const ServerView*> views(
      wm_connection()->GetViewTree(*wm_connection()->root()));
  ASSERT_EQ(5u, views.size());
  ASSERT_TRUE(views[0]->id() == *wm_connection()->root());
  ASSERT_TRUE(views[1]->id() == embed_view_id);
  ASSERT_TRUE(views[2]->id() == child1);
  ASSERT_TRUE(views[3]->id() == child2);
  ASSERT_TRUE(views[4]->id() == child3);

  // Verify connection1 doesn't see any cloned views.
  std::vector<const ServerView*> v1_views(
      connection1->GetViewTree(embed_view_id));
  ASSERT_EQ(4u, v1_views.size());
  ASSERT_TRUE(v1_views[0]->id() == embed_view_id);
  ASSERT_TRUE(v1_views[1]->id() == child1);
  ASSERT_TRUE(v1_views[2]->id() == child2);
  ASSERT_TRUE(v1_views[3]->id() == child3);
}

TEST_F(ViewManagerServiceTest, ClonedViewsPromotedOnConnectionClose) {
  ViewId embed_view_id;
  EXPECT_NO_FATAL_FAILURE(SetUpAnimate1(this, &embed_view_id));

  // Destroy connection1, which should force the cloned view to become a child
  // of where it was embedded (the embedded view still exists).
  connection_manager()->OnConnectionError(last_client_connection());

  ServerView* embed_view = wm_connection()->GetView(embed_view_id);
  ASSERT_TRUE(embed_view != nullptr);
  const ServerView* cloned_view = GetFirstCloned(embed_view);
  ASSERT_TRUE(cloned_view);
  ASSERT_EQ(1u, cloned_view->GetChildren().size());
  EXPECT_TRUE(cloned_view->GetChildren()[0]->id() == ClonedViewId());

  // Because the cloned view changed parents its bounds should have changed.
  EXPECT_EQ(gfx::Rect(3, 5, 6, 7), cloned_view->bounds());
  // The bounds of the cloned child should not have changed though.
  EXPECT_EQ(gfx::Rect(3, 4, 6, 7), cloned_view->GetChildren()[0]->bounds());
}

TEST_F(ViewManagerServiceTest, ClonedViewsPromotedOnHide) {
  ViewId embed_view_id;
  EXPECT_NO_FATAL_FAILURE(SetUpAnimate1(this, &embed_view_id));

  ViewManagerServiceImpl* connection1 =
      connection_manager()->GetConnectionWithRoot(embed_view_id);

  // Hide the parent of the cloned view, which should force the cloned view to
  // become a sibling of the parent.
  const ServerView* view_to_hide =
      connection1->GetView(ViewId(connection1->id(), 1));
  ASSERT_TRUE(connection1->SetViewVisibility(view_to_hide->id(), false));

  const ServerView* cloned_view = GetFirstCloned(view_to_hide->parent());
  ASSERT_TRUE(cloned_view);
  ASSERT_EQ(1u, cloned_view->GetChildren().size());
  EXPECT_TRUE(cloned_view->GetChildren()[0]->id() == ClonedViewId());
  EXPECT_EQ(2u, cloned_view->parent()->GetChildren().size());
  EXPECT_TRUE(cloned_view->parent()->GetChildren()[1] == cloned_view);
}

// Clone and animate on a tree with more depth. Basically that of
// SetUpAnimate1() but cloning 2,1.
TEST_F(ViewManagerServiceTest, CloneAndAnimateLargerDepth) {
  const ViewId embed_view_id(wm_connection()->id(), 1);
  EXPECT_EQ(ERROR_CODE_NONE, wm_connection()->CreateView(embed_view_id));
  EXPECT_TRUE(wm_connection()->SetViewVisibility(embed_view_id, true));
  EXPECT_TRUE(
      wm_connection()->AddView(*(wm_connection()->root()), embed_view_id));
  wm_connection()->EmbedUrl(std::string(), embed_view_id, nullptr, nullptr);
  ViewManagerServiceImpl* connection1 =
      connection_manager()->GetConnectionWithRoot(embed_view_id);
  ASSERT_TRUE(connection1 != nullptr);
  ASSERT_NE(connection1, wm_connection());

  const ViewId child1(connection1->id(), 1);
  EXPECT_EQ(ERROR_CODE_NONE, connection1->CreateView(child1));
  const ViewId child2(connection1->id(), 2);
  EXPECT_EQ(ERROR_CODE_NONE, connection1->CreateView(child2));
  const ViewId child3(connection1->id(), 3);
  EXPECT_EQ(ERROR_CODE_NONE, connection1->CreateView(child3));

  ServerView* v1 = connection1->GetView(child1);
  v1->SetVisible(true);
  connection1->GetView(child2)->SetVisible(true);
  connection1->GetView(child3)->SetVisible(true);

  EXPECT_TRUE(connection1->AddView(embed_view_id, child1));
  EXPECT_TRUE(connection1->AddView(child1, child2));
  EXPECT_TRUE(connection1->AddView(child2, child3));

  TestViewManagerClient* connection1_client = last_view_manager_client();
  connection1_client->tracker()->changes()->clear();
  wm_client()->tracker()->changes()->clear();
  EXPECT_TRUE(connection_manager()->CloneAndAnimate(child1));
  EXPECT_TRUE(connection1_client->tracker()->changes()->empty());
  EXPECT_TRUE(wm_client()->tracker()->changes()->empty());

  // We cloned v1. The cloned view ends up as a sibling of it.
  const ServerView* cloned_view = GetFirstCloned(v1->parent());
  ASSERT_TRUE(cloned_view);
  // |cloned_view| should have a child and its child should have a child.
  ASSERT_EQ(1u, cloned_view->GetChildren().size());
  const ServerView* cloned_view_child = cloned_view->GetChildren()[0];
  EXPECT_EQ(1u, cloned_view_child->GetChildren().size());
  EXPECT_TRUE(cloned_view_child->id() == ClonedViewId());
}

}  // namespace view_manager
