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

#include <stddef.h>

#include <algorithm>
#include <map>
#include <vector>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/browser_test.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/shell/browser/shell.h"
#include "content/shell/common/shell_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image.h"

namespace content {

namespace {

static const char kCanvasPageString[] =
    "<body>"
    "  <canvas id=\"canvas\" width=\"64\" height=\"64\""
    "    style=\"position:absolute;top:0px;left:0px;width:100%;"
    "    height=100%;margin:0;padding:0;\">"
    "  </canvas>"
    "  <script>"
    "    window.ctx = document.getElementById(\"canvas\").getContext(\"2d\");"
    "    function fillWithColor(color) {"
    "      ctx.fillStyle = color;"
    "      ctx.fillRect(0, 0, 64, 64);"
    "      return color;"
    "    }"
    "    var offset = 150;"
    "    function openNewWindow() {"
    "      window.open(\"/test\", \"\", "
    "          \"top=\"+offset+\",left=\"+offset+\",width=200,height=200\");"
    "      offset += 50;"
    "      return true;"
    "    }"
    "    window.document.title = \"Ready\";"
    "  </script>"
    "</body>";
}

class SnapshotBrowserTest : public ContentBrowserTest {
 public:
  SnapshotBrowserTest() {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // Use a smaller browser window to speed up the snapshots.
    command_line->AppendSwitchASCII(::switches::kContentShellHostWindowSize,
                                    "200x200");
  }

  void SetUp() override {
    // These tests rely on the harness producing pixel output.
    EnablePixelOutput();
    ContentBrowserTest::SetUp();
  }

  content::WebContentsImpl* GetWebContents(Shell* browser) {
    return static_cast<content::WebContentsImpl*>(browser->web_contents());
  }

  content::RenderWidgetHostImpl* GetRenderWidgetHostImpl(Shell* browser) {
    return GetWebContents(browser)->GetRenderViewHost()->GetWidget();
  }

  void SetupTestServer() {
    // Use an embedded test server so we can open multiple windows in
    // the same renderer process, all referring to the same origin.
    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
        &SnapshotBrowserTest::HandleRequest, base::Unretained(this)));
    ASSERT_TRUE(embedded_test_server()->Start());

    ASSERT_TRUE(
        NavigateToURL(shell(), embedded_test_server()->GetURL("/test")));
  }

  std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
      const net::test_server::HttpRequest& request) {
    GURL absolute_url = embedded_test_server()->GetURL(request.relative_url);
    if (absolute_url.GetPath() != "/test") {
      return nullptr;
    }

    std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
        new net::test_server::BasicHttpResponse());
    http_response->set_code(net::HTTP_OK);
    http_response->set_content(kCanvasPageString);
    http_response->set_content_type("text/html");
    return http_response;
  }

  void WaitForAllWindowsToBeReady() {
    const std::u16string expected_title = u"Ready";
    // The subordinate windows may load asynchronously. Wait for all of
    // them to execute their script before proceeding.
    auto browser_list = Shell::windows();
    for (Shell* browser : browser_list) {
      TitleWatcher watcher(GetWebContents(browser), expected_title);
      const std::u16string& actual_title = watcher.WaitAndGetTitle();
      EXPECT_EQ(expected_title, actual_title);
    }
  }

  struct ExpectedColor {
    ExpectedColor() : r(0), g(0), b(0) {}
    bool operator==(const ExpectedColor& other) const {
      return (r == other.r && g == other.g && b == other.b);
    }
    uint8_t r;
    uint8_t g;
    uint8_t b;
  };

  void PickRandomColor(ExpectedColor* expected) {
    expected->r = static_cast<uint8_t>(base::RandInt(0, 256));
    expected->g = static_cast<uint8_t>(base::RandInt(0, 256));
    expected->b = static_cast<uint8_t>(base::RandInt(0, 256));
  }

  struct SerialSnapshot {
    SerialSnapshot() : host(nullptr) {}

    raw_ptr<content::RenderWidgetHost> host;
    ExpectedColor color;
  };
  std::vector<SerialSnapshot> expected_snapshots_;

  void SyncSnapshotCallback(content::RenderWidgetHostImpl* rwhi,
                            const gfx::Image& image) {
    for (auto iter = expected_snapshots_.begin();
         iter != expected_snapshots_.end(); ++iter) {
      const SerialSnapshot& expected = *iter;
      if (expected.host == rwhi) {
        const SkBitmap* bitmap = image.ToSkBitmap();
        SkColor color = bitmap->getColor(1, 1);

        EXPECT_EQ(static_cast<int>(SkColorGetR(color)),
                  static_cast<int>(expected.color.r))
            << "Red channels differed";
        EXPECT_EQ(static_cast<int>(SkColorGetG(color)),
                  static_cast<int>(expected.color.g))
            << "Green channels differed";
        EXPECT_EQ(static_cast<int>(SkColorGetB(color)),
                  static_cast<int>(expected.color.b))
            << "Blue channels differed";

        expected_snapshots_.erase(iter);
        break;
      }
    }
  }

  std::map<content::RenderWidgetHost*, std::vector<ExpectedColor>>
      expected_async_snapshots_map_;
  int num_remaining_async_snapshots_ = 0;

  void AsyncSnapshotCallback(content::RenderWidgetHostImpl* rwhi,
                             const gfx::Image& image) {
    --num_remaining_async_snapshots_;
    auto iterator = expected_async_snapshots_map_.find(rwhi);
    ASSERT_NE(iterator, expected_async_snapshots_map_.end());
    std::vector<ExpectedColor>& expected_snapshots = iterator->second;
    const SkBitmap* bitmap = image.ToSkBitmap();
    SkColor color = bitmap->getColor(1, 1);
    bool found = false;
    // Find first instance of this color in the list and clear out all
    // of the entries before that point. If it's not found, report
    // failure.
    for (auto iter = expected_snapshots.begin();
         iter != expected_snapshots.end(); ++iter) {
      const ExpectedColor& expected = *iter;
      if (SkColorGetR(color) == expected.r &&
          SkColorGetG(color) == expected.g &&
          SkColorGetB(color) == expected.b) {
        // Erase everything up to this color, but not this color
        // itself, since it might be returned again later on
        // subsequent snapshot requests.
        expected_snapshots.erase(expected_snapshots.begin(), iter);
        found = true;
        break;
      }
    }

    EXPECT_TRUE(found) << "Did not find color ("
                       << static_cast<int>(SkColorGetR(color)) << ", "
                       << static_cast<int>(SkColorGetG(color)) << ", "
                       << static_cast<int>(SkColorGetB(color))
                       << ") in expected snapshots for RWH 0x" << rwhi;
  }
};

// Even the single-window test doesn't work on Android yet. It's expected
// that the multi-window tests would never work on that platform.
#if !BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_MAC)
// TODO(crbug.com/40854618): This test is flakey on macOS.
#define MAYBE_SingleWindowTest DISABLED_SingleWindowTest
#else
#define MAYBE_SingleWindowTest SingleWindowTest
#endif
IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SingleWindowTest) {
  SetupTestServer();

  content::RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(shell());

  for (int i = 0; i < 40; ++i) {
    SerialSnapshot expected;
    expected.host = rwhi;
    PickRandomColor(&expected.color);

    std::string colorString = base::StringPrintf(
        "#%02x%02x%02x", expected.color.r, expected.color.g, expected.color.b);
    std::string script = std::string("fillWithColor(\"") + colorString + "\");";
    EXPECT_EQ(colorString, EvalJs(GetWebContents(shell()), script));

    expected_snapshots_.push_back(expected);

    // Get the snapshot from the surface rather than the window. The
    // on-screen display path is verified by the GPU tests, and it
    // seems difficult to figure out the colorspace transformation
    // required to make these color comparisons.
    rwhi->GetSnapshotFromBrowser(
        base::BindOnce(&SnapshotBrowserTest::SyncSnapshotCallback,
                       base::Unretained(this), base::Unretained(rwhi)),
        true);
    while (expected_snapshots_.size() > 0) {
      base::RunLoop().RunUntilIdle();
    }
  }
}

// Timing out either all the time, or infrequently, apparently because
// they're too slow, on the following configurations:
//   Windows Debug
//   Windows Release (https://crbug.com/1376441)
//   Linux Chromium OS ASAN LSAN Tests (1)
//   Linux TSAN Tests
// See crbug.com/771119
// TODO(crbug.com/40834774): Fix and enable on Fuchsia.
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) || \
    (BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER))
#define MAYBE_SyncMultiWindowTest DISABLED_SyncMultiWindowTest
#else
#define MAYBE_SyncMultiWindowTest SyncMultiWindowTest
#endif
IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) {
  SetupTestServer();

  for (int i = 0; i < 3; ++i) {
    EXPECT_EQ(true, EvalJs(GetWebContents(shell()), "openNewWindow()"));
  }

  base::RunLoop().RunUntilIdle();

  WaitForAllWindowsToBeReady();

  auto browser_list = Shell::windows();
  EXPECT_EQ(4u, browser_list.size());

  for (int i = 0; i < 20; ++i) {
    for (int j = 0; j < 4; j++) {
      // Start each iteration by taking a snapshot with a different
      // browser instance.
      int browser_index = (i + j) % 4;
      Shell* browser = browser_list[browser_index];
      content::RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(browser);

      SerialSnapshot expected;
      expected.host = rwhi;
      PickRandomColor(&expected.color);

      std::string colorString =
          base::StringPrintf("#%02x%02x%02x", expected.color.r,
                             expected.color.g, expected.color.b);
      std::string script =
          std::string("fillWithColor(\"") + colorString + "\");";
      EXPECT_EQ(colorString, EvalJs(GetWebContents(browser), script));
      expected_snapshots_.push_back(expected);
      // Get the snapshot from the surface rather than the window. The
      // on-screen display path is verified by the GPU tests, and it
      // seems difficult to figure out the colorspace transformation
      // required to make these color comparisons.
      rwhi->GetSnapshotFromBrowser(
          base::BindOnce(&SnapshotBrowserTest::SyncSnapshotCallback,
                         base::Unretained(this), base::Unretained(rwhi)),
          true);
    }

    while (expected_snapshots_.size() > 0) {
      base::RunLoop().RunUntilIdle();
    }
  }
}

// Timing out either all the time, or infrequently, apparently because
// they're too slow, on the following configurations:
//   Windows Debug
//   Linux Chromium OS ASAN LSAN Tests (1)
//   Linux TSAN Tests
// See crbug.com/771119
// TODO(crbug.com/40740836): recently crashes flakily on
// linux_chromium_asan_rel_ng and linux-rel.
// TODO(crbug.com/40834774): Fix and enable on Fuchsia.
#if (BUILDFLAG(IS_WIN) && !defined(NDEBUG)) || BUILDFLAG(IS_CHROMEOS) || \
    BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA)
#define MAYBE_AsyncMultiWindowTest DISABLED_AsyncMultiWindowTest
#else
#define MAYBE_AsyncMultiWindowTest AsyncMultiWindowTest
#endif
IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_AsyncMultiWindowTest) {
  SetupTestServer();

  for (int i = 0; i < 3; ++i) {
    EXPECT_EQ(true, EvalJs(GetWebContents(shell()), "openNewWindow()"));
  }

  base::RunLoop().RunUntilIdle();

  WaitForAllWindowsToBeReady();

  auto browser_list = Shell::windows();
  EXPECT_EQ(4u, browser_list.size());

  // This many pending snapshots per window will be put on the queue
  // before draining the requests. Anything more than 1 seems to catch
  // bugs which might otherwise be introduced in LatencyInfo's
  // propagation of the BROWSER_SNAPSHOT_FRAME_NUMBER_COMPONENT
  // component type.
  int divisor = 3;

  for (int i = 0; i < 10 * divisor; ++i) {
    for (int j = 0; j < 4; j++) {
      // Start each iteration by taking a snapshot with a different
      // browser instance.
      int browser_index = (i + j) % 4;
      Shell* browser = browser_list[browser_index];
      content::RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(browser);

      std::vector<ExpectedColor>& expected_snapshots =
          expected_async_snapshots_map_[rwhi];

      // Pick a unique random color.
      ExpectedColor expected;
      do {
        PickRandomColor(&expected);
      } while (base::Contains(expected_snapshots, expected));
      expected_snapshots.push_back(expected);

      std::string colorString = base::StringPrintf("#%02x%02x%02x", expected.r,
                                                   expected.g, expected.b);
      std::string script =
          std::string("fillWithColor(\"") + colorString + "\");";
      EXPECT_EQ(colorString, EvalJs(GetWebContents(browser), script));
      // Get the snapshot from the surface rather than the window. The
      // on-screen display path is verified by the GPU tests, and it
      // seems difficult to figure out the colorspace transformation
      // required to make these color comparisons.
      rwhi->GetSnapshotFromBrowser(
          base::BindOnce(&SnapshotBrowserTest::AsyncSnapshotCallback,
                         base::Unretained(this), base::Unretained(rwhi)),
          true);
      ++num_remaining_async_snapshots_;
    }

    // Periodically yield and drain the async snapshot requests.
    if ((i % divisor) == 0) {
      bool drained;
      do {
        drained = true;
        for (auto iter = expected_async_snapshots_map_.begin();
             iter != expected_async_snapshots_map_.end(); ++iter) {
          if (iter->second.size() > 1) {
            drained = false;
            break;
          }
        }
        if (!drained) {
          base::RunLoop().RunUntilIdle();
        }
      } while (!drained);
    }
  }

  // At the end of the test, cooperatively wait for all of the snapshot
  // requests to be drained before exiting. This works around crashes
  // seen when tearing down the compositor while these requests are in
  // flight. Likely, user-visible APIs that use this facility are safe
  // in this regard.
  while (num_remaining_async_snapshots_ > 0) {
    base::RunLoop().RunUntilIdle();
  }
}

#endif  // !BUILDFLAG(IS_ANDROID)

}  // namespace content
