// 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 <lib/fit/function.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>

#include <gtest/gtest.h>

#include "src/chromium/web_runner_tests/test_server.h"
#include "src/chromium/web_runner_tests/web_context.h"
#include "src/lib/fxl/strings/string_printf.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/+/HEAD/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/+/HEAD/fuchsia/runners/web/web_runner_smoke_test.cc
TEST(WebRunnerIntegrationTest, Smoke) {
  web_runner_tests::TestServer server;
  FX_CHECK(server.FindAndBindPort());

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

  fuchsia::sys::LauncherSyncPtr launcher;
  sys::ServiceDirectory::CreateFromNamespace()->Connect(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()));

  FX_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 MockNavigationEventListener : public fuchsia::web::NavigationEventListener {
 public:
  // |fuchsia::web::NavigationEventListener|
  void OnNavigationStateChanged(fuchsia::web::NavigationState 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(fuchsia::web::NavigationState)> fn) {
    on_navigation_state_changed_ = std::move(fn);
  }

 private:
  fit::function<void(fuchsia::web::NavigationState)> on_navigation_state_changed_;
};

class ChromiumAppTest : public gtest::RealLoopFixture {
 protected:
  ChromiumAppTest()
      : web_context_(sys::ComponentContext::CreateAndServeOutgoingDirectory().get(),
                     fuchsia::web::ContextFeatureFlags()) {}

  WebContext* web_context() { return &web_context_; }

 private:
  WebContext web_context_;
};

// This test ensures that we can interact with the fuchsia.web FIDL.
//
// See also
// https://chromium.googlesource.com/chromium/src/+/HEAD/fuchsia/engine/browser/context_impl_browsertest.cc
TEST_F(ChromiumAppTest, CreateAndNavigate) {
  MockNavigationEventListener navigation_event_listener;
  fidl::Binding<fuchsia::web::NavigationEventListener> navigation_event_listener_binding(
      &navigation_event_listener);
  web_context()->web_frame()->SetNavigationEventListener(
      navigation_event_listener_binding.NewBinding());
  navigation_event_listener_binding.set_error_handler([](zx_status_t status) {
    FAIL() << "navigation_event_listener_binding: " << zx_status_get_string(status);
  });

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

  navigation_event_listener.set_on_navigation_state_changed(
      [this, &navigation_event_listener, &observed_url,
       &observed_title](fuchsia::web::NavigationState change) {
        if (change.has_url()) {
          observed_url = change.url();
        }
        if (change.has_title()) {
          observed_title = change.title();
        }

        if (change.has_page_type()) {
          EXPECT_EQ(change.page_type(), fuchsia::web::PageType::NORMAL);
        }

        if (change.has_is_main_document_loaded() && change.is_main_document_loaded()) {
          navigation_event_listener.set_on_navigation_state_changed(nullptr);
          QuitLoop();
        }
      });

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

  const std::string url = fxl::StringPrintf("http://localhost:%d/foo.html", server.port());
  web_context()->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()));
  FX_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
