// 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/fit/function.h>
#include <lib/gtest/real_loop_fixture.h>
#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/strings/string_printf.h>
#include <zircon/status.h>

#include "lib/sys/cpp/service_directory.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;
  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()));

  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_(sys::ComponentContext::Create().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();
        }
      });

  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
