// Copyright 2015 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/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/renderer/render_frame_impl.h"
#include "content/shell/browser/shell.h"

namespace content {

class CommitObserver : public RenderViewObserver {
 public:
  CommitObserver(RenderView* render_view)
      : RenderViewObserver(render_view), quit_closures_(), commit_count_(0) {}

  void DidCommitCompositorFrame() override {
    commit_count_++;
    for (base::Closure* closure : quit_closures_) {
      closure->Run();
    }
  }

  void QuitAfterCommit(int commit_number,
                       scoped_refptr<MessageLoopRunner> runner) {
    if (commit_number >= commit_count_) runner->Quit();
  }

  void WaitForCommitNumber(int commit_number) {
    if (commit_number > commit_count_) {
      scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
      base::Closure quit_closure =
          base::Bind(&CommitObserver::QuitAfterCommit, base::Unretained(this),
                     commit_number, runner);
      quit_closures_.insert(&quit_closure);
      runner->Run();
      quit_closures_.erase(&quit_closure);
    }
  }

  int GetCommitCount() { return commit_count_; }

 private:
  // RenderViewObserver implementation.
  void OnDestruct() override { delete this; }

  std::set<base::Closure*> quit_closures_;
  int commit_count_;
};

class VisualStateTest : public ContentBrowserTest {
 public:
  VisualStateTest() : callback_count_(0) {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kSingleProcess);
  }

  void WaitForCommit(CommitObserver *observer, int commit_number) {
    observer->WaitForCommitNumber(commit_number);
    EXPECT_EQ(commit_number, observer->GetCommitCount());
  }

  void AssertIsIdle() {
    ASSERT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
  }

  void InvokeVisualStateCallback(bool result) {
    EXPECT_TRUE(result);
    callback_count_++;
  }

  int GetCallbackCount() { return callback_count_; }

 private:
  int callback_count_;
};

// This test verifies that visual state callbacks do not deadlock. In other
// words, the visual state callback should be received even if there are no
// pending updates or commits.
// Disabled due to cross-platform flakes; http://crbug.com/462580.
IN_PROC_BROWSER_TEST_F(VisualStateTest, DISABLED_CallbackDoesNotDeadlock) {
  // This test relies on the fact that loading "about:blank" only requires a
  // single commit. We first load "about:blank" and wait for this single
  // commit. At that point we know that the page has stabilized and no
  // further commits are expected. We then insert a visual state callback
  // and verify that this causes an additional commit in order to deliver
  // the callback.
  // Unfortunately, if loading "about:blank" changes and starts requiring
  // two commits then this test will prove nothing. We could detect this
  // with a high level of confidence if we used a timeout, but that's
  // discouraged (see https://codereview.chromium.org/939673002).
  NavigateToURL(shell(), GURL("about:blank"));
  CommitObserver observer(RenderView::FromRoutingID(
      shell()->web_contents()->GetRenderViewHost()->GetRoutingID()));

  // Wait for the commit corresponding to the load.

  PostTaskToInProcessRendererAndWait(base::Bind(
      &VisualStateTest::WaitForCommit, base::Unretained(this), &observer, 1));

  // Try our best to check that there are no pending updates or commits.
  PostTaskToInProcessRendererAndWait(
      base::Bind(&VisualStateTest::AssertIsIdle, base::Unretained(this)));

  // Insert a visual state callback.
  shell()->web_contents()->GetMainFrame()->InsertVisualStateCallback(base::Bind(
      &VisualStateTest::InvokeVisualStateCallback, base::Unretained(this)));

  // Verify that the callback is invoked and a new commit completed.
  PostTaskToInProcessRendererAndWait(base::Bind(
      &VisualStateTest::WaitForCommit, base::Unretained(this), &observer, 2));
  EXPECT_EQ(1, GetCallbackCount());
}

}  // namespace content
