// Copyright 2018 The Fuchsia 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 <fuchsia/sys/cpp/fidl.h>
#include <gtest/gtest.h>
#include <lib/component/cpp/environment_services_helper.h>
#include <lib/fit/function.h>
#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/strings/string_printf.h>
#include <lib/gtest/real_loop_fixture.h>
#include <zircon/status.h>

#include "topaz/tests/web_runner_tests/chromium_context.h"
#include "topaz/tests/web_runner_tests/test_server.h"

// This file contains a subset of adapted Chromium Fuchsia tests to make sure
// nothing broke on the import boundary.
//
// See also: https://chromium.googlesource.com/chromium/src/+/master/fuchsia
namespace {

// This is a black box smoke test for whether the web runner in a given system
// is capable of performing basic operations.
//
// This tests if launching a component with an HTTP URL triggers an HTTP GET for
// the main resource, and if an HTML response with an <img> tag triggers a
// subresource load for the image.
//
// See also:
// https://chromium.googlesource.com/chromium/src/+/master/fuchsia/runners/web/web_runner_smoke_test.cc
TEST(WebRunnerIntegrationTest, Smoke) {
  web_runner_tests::TestServer server;
  FXL_CHECK(server.FindAndBindPort());

  fuchsia::sys::LaunchInfo launch_info;
  launch_info.url =
      fxl::StringPrintf("http://localhost:%d/foo.html", server.port());

  fuchsia::sys::LauncherSyncPtr launcher;
  component::GetEnvironmentServices()->ConnectToService(launcher.NewRequest());

  fuchsia::sys::ComponentControllerSyncPtr controller;
  launcher->CreateComponent(std::move(launch_info), controller.NewRequest());

  ASSERT_TRUE(server.Accept());

  std::string expected_prefix = "GET /foo.html HTTP";
  // We need to overallocate the first time to drain the read since we expect
  // the subsresource load on the same connection.
  std::string buf(4096, 0);
  ASSERT_TRUE(server.Read(&buf));
  EXPECT_EQ(expected_prefix, buf.substr(0, expected_prefix.size()));

  FXL_CHECK(server.WriteContent("<!doctype html><img src=\"/img.png\">"));

  expected_prefix = "GET /img.png HTTP";
  buf.resize(expected_prefix.size());
  ASSERT_TRUE(server.Read(&buf));

  ASSERT_GE(buf.size(), expected_prefix.size());
  EXPECT_EQ(expected_prefix, std::string(buf.data(), expected_prefix.size()));
}

class MockNavigationEventObserver
    : public chromium::web::NavigationEventObserver {
 public:
  // |chromium::web::NavigationEventObserver|
  void OnNavigationStateChanged(
      chromium::web::NavigationEvent change,
      OnNavigationStateChangedCallback callback) override {
    if (on_navigation_state_changed_) {
      on_navigation_state_changed_(std::move(change));
    }

    callback();
  }

  void set_on_navigation_state_changed(
      fit::function<void(chromium::web::NavigationEvent)> fn) {
    on_navigation_state_changed_ = std::move(fn);
  }

 private:
  fit::function<void(chromium::web::NavigationEvent)>
      on_navigation_state_changed_;
};

class ChromiumAppTest : public gtest::RealLoopFixture {
 protected:
  ChromiumAppTest()
      : chromium_(component::StartupContext::CreateFromStartupInfo().get()) {}

  ChromiumContext* chromium() { return &chromium_; }

 private:
  ChromiumContext chromium_;
};

// This test ensures that we can interact with the chromium.web FIDL.
//
// See also
// https://chromium.googlesource.com/chromium/src/+/master/fuchsia/engine/browser/context_impl_browsertest.cc
TEST_F(ChromiumAppTest, CreateAndNavigate) {
  MockNavigationEventObserver navigation_event_observer;
  fidl::Binding<chromium::web::NavigationEventObserver>
      navigation_event_observer_binding(&navigation_event_observer);
  chromium()->frame()->SetNavigationEventObserver(
      navigation_event_observer_binding.NewBinding());
  navigation_event_observer_binding.set_error_handler([](zx_status_t status) {
    FAIL() << "navigation_event_observer_binding: "
           << zx_status_get_string(status);
  });

  std::string observed_url;
  std::string observed_title;

  navigation_event_observer.set_on_navigation_state_changed(
      [this, &navigation_event_observer, &observed_url,
       &observed_title](chromium::web::NavigationEvent change) {
        if (change.url) {
          observed_url = *change.url;
        }
        if (change.title) {
          observed_title = *change.title;
        }

        EXPECT_FALSE(change.is_error);

        if (!(observed_url.empty() || observed_title.empty())) {
          navigation_event_observer.set_on_navigation_state_changed(nullptr);
          QuitLoop();
        }
      });

  // TODO(NET-2089): Without this (or even if this is moved down below
  // |FindAndBindPort|), this test flakes about 10% of the time. Reordering the
  // tests such that this test executes first also deflakes it.
  sleep(1);

  web_runner_tests::TestServer server;
  FXL_CHECK(server.FindAndBindPort());

  const std::string url =
      fxl::StringPrintf("http://localhost:%d/foo.html", server.port());
  chromium()->Navigate(url);

  ASSERT_TRUE(server.Accept());

  const std::string expected_prefix = "GET /foo.html HTTP";
  std::string buf(expected_prefix.size(), 0);
  ASSERT_TRUE(server.Read(&buf));
  EXPECT_EQ(expected_prefix, buf.substr(0, expected_prefix.size()));
  FXL_CHECK(server.WriteContent(R"(<!doctype html>
      <html>
        <head>
          <title>Test title!</title>
        </head>
      </html>)"));

  EXPECT_FALSE(RunLoopWithTimeout(zx::sec(5)))
      << "Timed out waiting for navigation events";

  EXPECT_EQ(url, observed_url);
  EXPECT_EQ("Test title!", observed_title);
}

}  // namespace