// 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 "base/bind.h"
#include "base/command_line.h"
#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/application/service_provider_impl.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/view.h"
#include "mojo/services/view_manager/public/cpp/view_manager.h"
#include "mojo/services/view_manager/public/cpp/view_manager_client_factory.h"
#include "mojo/services/view_manager/public/cpp/view_manager_delegate.h"
#include "mojo/services/view_manager/public/interfaces/view_manager.mojom.h"
#include "mojo/services/window_manager/public/interfaces/window_manager.mojom.h"
#include "shell/application_manager/application_manager.h"
#include "shell/shell_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"

using mojo::ApplicationImpl;
using mojo::Id;
using mojo::View;

namespace window_manager {
namespace {

const char kTestServiceURL[] = "mojo:test_url";

void EmptyResultCallback(bool result) {}

class TestWindowManagerClient : public mojo::WindowManagerClient {
 public:
  typedef base::Callback<void(Id, Id)>
      TwoNodeCallback;

  explicit TestWindowManagerClient(base::RunLoop* run_loop)
      : run_loop_(run_loop) {}
  ~TestWindowManagerClient() override {}

  void set_focus_changed_callback(const TwoNodeCallback& callback) {
    focus_changed_callback_ = callback;
  }
  void set_active_window_changed_callback(const TwoNodeCallback& callback) {
    active_window_changed_callback_ = callback;
  }

 private:
  // Overridden from mojo::WindowManagerClient:
  void OnCaptureChanged(Id old_capture_node_id,
                        Id new_capture_node_id) override {}
  void OnFocusChanged(Id old_focused_node_id, Id new_focused_node_id) override {
    if (!focus_changed_callback_.is_null())
      focus_changed_callback_.Run(old_focused_node_id, new_focused_node_id);
  }
  void OnActiveWindowChanged(Id old_active_window,
                             Id new_active_window) override {
    if (!active_window_changed_callback_.is_null())
      active_window_changed_callback_.Run(old_active_window, new_active_window);
  }

  base::RunLoop* run_loop_;
  TwoNodeCallback focus_changed_callback_;
  TwoNodeCallback active_window_changed_callback_;

  DISALLOW_COPY_AND_ASSIGN(TestWindowManagerClient);
};

class TestApplicationLoader : public mojo::ApplicationLoader,
                              public mojo::ApplicationDelegate,
                              public mojo::ViewManagerDelegate {
 public:
  typedef base::Callback<void(View*)> RootAddedCallback;

  explicit TestApplicationLoader(const RootAddedCallback& root_added_callback)
      : root_added_callback_(root_added_callback) {}
  ~TestApplicationLoader() override {}

 private:
  // Overridden from mojo::ApplicationLoader:
  void Load(mojo::ApplicationManager* application_manager,
            const GURL& url,
            mojo::ScopedMessagePipeHandle shell_handle,
            LoadCallback callback) override {
    ASSERT_TRUE(shell_handle.is_valid());
    scoped_ptr<ApplicationImpl> app(
        new ApplicationImpl(this, shell_handle.Pass()));
    apps_.push_back(app.release());
  }
  void OnApplicationError(mojo::ApplicationManager* application_manager,
                          const GURL& url) override {}

  // Overridden from mojo::ApplicationDelegate:
  void Initialize(ApplicationImpl* app) override {
    view_manager_client_factory_.reset(
        new mojo::ViewManagerClientFactory(app->shell(), this));
  }

  bool ConfigureIncomingConnection(
      mojo::ApplicationConnection* connection) override {
    connection->AddService(view_manager_client_factory_.get());
    return true;
  }

  // Overridden from mojo::ViewManagerDelegate:
  void OnEmbed(View* root,
               mojo::ServiceProviderImpl* exported_services,
               scoped_ptr<mojo::ServiceProvider> imported_services) override {
    root_added_callback_.Run(root);
  }
  void OnViewManagerDisconnected(mojo::ViewManager* view_manager) override {}

  RootAddedCallback root_added_callback_;

  ScopedVector<ApplicationImpl> apps_;
  scoped_ptr<mojo::ViewManagerClientFactory> view_manager_client_factory_;

  DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
};

}  // namespace

class WindowManagerApiTest : public testing::Test {
 public:
  WindowManagerApiTest() {}
  ~WindowManagerApiTest() override {}

 protected:
  typedef std::pair<Id, Id> TwoIds;

  Id WaitForEmbed() {
    Id id;
    base::RunLoop run_loop;
    root_added_callback_ = base::Bind(&WindowManagerApiTest::OnEmbed,
                                      base::Unretained(this), &id, &run_loop);
    run_loop.Run();
    return id;
  }

  TwoIds WaitForFocusChange() {
    TwoIds old_and_new;
    base::RunLoop run_loop;
    window_manager_client()->set_focus_changed_callback(
        base::Bind(&WindowManagerApiTest::OnFocusChanged,
                   base::Unretained(this), &old_and_new, &run_loop));
    run_loop.Run();
    return old_and_new;
  }

  TwoIds WaitForActiveWindowChange() {
    TwoIds old_and_new;
    base::RunLoop run_loop;
    window_manager_client()->set_active_window_changed_callback(
        base::Bind(&WindowManagerApiTest::OnActiveWindowChanged,
                   base::Unretained(this), &old_and_new, &run_loop));
    run_loop.Run();
    return old_and_new;
  }

  Id OpenWindow() {
    return OpenWindowWithURL(kTestServiceURL);
  }

  Id OpenWindowWithURL(const std::string& url) {
    base::RunLoop run_loop;
    mojo::ServiceProviderPtr sp;
    BindToProxy(new mojo::ServiceProviderImpl, &sp);
    window_manager_->Embed(
        url, mojo::MakeRequest<mojo::ServiceProvider>(sp.PassMessagePipe()));
    run_loop.Run();
    return WaitForEmbed();
  }

  TestWindowManagerClient* window_manager_client() {
    return window_manager_client_.get();
  }

  mojo::WindowManagerPtr window_manager_;

 private:
  // Overridden from testing::Test:
  void SetUp() override {
    test_helper_.reset(new mojo::shell::ShellTestHelper);
    test_helper_->Init();
    test_helper_->AddCustomMapping(GURL("mojo:window_manager"),
                                   GURL("mojo:core_window_manager"));
    test_helper_->SetLoaderForURL(
        scoped_ptr<mojo::ApplicationLoader>(
            new TestApplicationLoader(base::Bind(
                &WindowManagerApiTest::OnRootAdded, base::Unretained(this)))),
        GURL(kTestServiceURL));
    ConnectToWindowManager2();
  }
  void TearDown() override {}

  void ConnectToWindowManager2() {
    test_helper_->application_manager()->ConnectToService(
        GURL("mojo:window_manager"), &window_manager_);
    base::RunLoop connect_loop;
    window_manager_client_.reset(new TestWindowManagerClient(&connect_loop));
    window_manager_.set_client(window_manager_client());
    connect_loop.Run();

    // The RunLoop above ensures the connection to the window manager completes.
    // Without this the ApplicationManager would load the window manager twice.
    test_helper_->application_manager()->ConnectToService(
        GURL("mojo:core_window_manager"), &window_manager_);
  }

  void OnRootAdded(View* root) {
    if (!root_added_callback_.is_null())
      root_added_callback_.Run(root);
  }

  void OnEmbed(Id* root_id,
               base::RunLoop* loop,
               View* root) {
    *root_id = root->id();
    loop->Quit();
  }

  void OnFocusChanged(TwoIds* old_and_new,
                      base::RunLoop* run_loop,
                      Id old_focused_node_id,
                      Id new_focused_node_id) {
    DCHECK(old_and_new);
    old_and_new->first = old_focused_node_id;
    old_and_new->second = new_focused_node_id;
    run_loop->Quit();
  }

  void OnActiveWindowChanged(TwoIds* old_and_new,
                             base::RunLoop* run_loop,
                             Id old_focused_node_id,
                             Id new_focused_node_id) {
    DCHECK(old_and_new);
    old_and_new->first = old_focused_node_id;
    old_and_new->second = new_focused_node_id;
    run_loop->Quit();
  }

  scoped_ptr<mojo::shell::ShellTestHelper> test_helper_;
  scoped_ptr<TestWindowManagerClient> window_manager_client_;
  TestApplicationLoader::RootAddedCallback root_added_callback_;

  DISALLOW_COPY_AND_ASSIGN(WindowManagerApiTest);
};

// TODO(sky): resolve this. Temporarily disabled as ApplicationManager ends up
// loading windowmanager twice because of the mapping of window_manager to
// core_window_manager.
TEST_F(WindowManagerApiTest, DISABLED_FocusAndActivateWindow) {
  Id first_window = OpenWindow();
  window_manager_->FocusWindow(first_window, base::Bind(&EmptyResultCallback));
  TwoIds ids = WaitForFocusChange();
  EXPECT_TRUE(ids.first == 0);
  EXPECT_EQ(ids.second, first_window);

  Id second_window = OpenWindow();
  window_manager_->ActivateWindow(second_window,
                                  base::Bind(&EmptyResultCallback));
  ids = WaitForActiveWindowChange();
  EXPECT_EQ(ids.first, first_window);
  EXPECT_EQ(ids.second, second_window);
}

}  // namespace window_manager
