// Copyright 2020 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 <fuchsia/logger/cpp/fidl.h>

#include <cstring>

#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/process_context.h"
#include "base/fuchsia/test_log_listener_safe.h"
#include "base/strings/string_piece.h"
#include "base/test/bind.h"
#include "fuchsia/base/context_provider_test_connector.h"
#include "fuchsia/base/frame_test_util.h"
#include "fuchsia/engine/web_engine_integration_test_base.h"

namespace {

// Name of the console logging test page.
constexpr char kLogTestPageFileName[] = "console_logging.html";
constexpr char kLogTestPageDebugMessage[] = "This is a debug() message.";

// Debug name to create Frames with, to use as their logging tag.
constexpr char kFrameLogTag[] = "Test🖼🪵";

constexpr char kNormalizedPortNumber[] = "678";

// Replaces the line number in frame_impl.cc with kNormalizedLineNumber and
// the port with kNormalizedPortNumber to enable reliable comparison of
// console log messages.
std::string NormalizeConsoleLogMessage(base::StringPiece original) {
  const char kSchemePortColon[] = "http://127.0.0.1:";
  size_t port_begin =
      original.find(kSchemePortColon) + strlen(kSchemePortColon);
  size_t path_begin = original.find("/", port_begin);
  return original.as_string().replace(port_begin, path_begin - port_begin,
                                      kNormalizedPortNumber);
}

}  // namespace

class WebEngineIntegrationLoggingTest : public WebEngineIntegrationTestBase {
 protected:
  WebEngineIntegrationLoggingTest()
      : WebEngineIntegrationTestBase(),
        isolated_archivist_service_dir_(
            StartIsolatedArchivist(archivist_controller_.NewRequest())) {}

  void SetUp() override {
    WebEngineIntegrationTestBase::SetUp();
    StartWebEngineForLoggingTest(
        base::CommandLine(base::CommandLine::NO_PROGRAM));

    logger_ = isolated_archivist_service_dir_.Connect<fuchsia::logger::Log>();
  }

  // Starts WebEngine without redirecting its logs.
  void StartWebEngineForLoggingTest(base::CommandLine command_line) {
    web_context_provider_ = cr_fuchsia::ConnectContextProviderForLoggingTest(
        web_engine_controller_.NewRequest(), std::move(command_line));
    web_context_provider_.set_error_handler(
        [](zx_status_t status) { ADD_FAILURE(); });
  }

  // Starts an isolated instance of Archivist to receive and dump log statements
  // via the fuchsia.logger.Log* APIs.
  fidl::InterfaceHandle<fuchsia::io::Directory> StartIsolatedArchivist(
      fidl::InterfaceRequest<fuchsia::sys::ComponentController>
          component_controller_request) {
    const char kArchivistUrl[] =
        "fuchsia-pkg://fuchsia.com/archivist-for-embedding#meta/"
        "archivist-for-embedding.cmx";

    fuchsia::sys::LaunchInfo launch_info;
    launch_info.url = kArchivistUrl;

    fidl::InterfaceHandle<fuchsia::io::Directory> archivist_services_dir;
    launch_info.directory_request =
        archivist_services_dir.NewRequest().TakeChannel();

    auto launcher = base::ComponentContextForProcess()
                        ->svc()
                        ->Connect<fuchsia::sys::Launcher>();
    launcher->CreateComponent(std::move(launch_info),
                              std::move(component_controller_request));

    return archivist_services_dir;
  }

  // Returns a CreateContextParams that has an isolated LogSink service from
  // |isolated_archivist_service_dir_|.
  fuchsia::web::CreateContextParams ContextParamsWithIsolatedLogSink() {
    // Use a FilteredServiceDirectory in order to inject an isolated service.
    fuchsia::web::CreateContextParams create_params =
        ContextParamsWithFilteredServiceDirectory();

    EXPECT_EQ(filtered_service_directory_->outgoing_directory()
                  ->RemovePublicService<fuchsia::logger::LogSink>(),
              ZX_OK);

    EXPECT_EQ(
        filtered_service_directory_->outgoing_directory()->AddPublicService(
            std::make_unique<vfs::Service>(
                [this](zx::channel channel, async_dispatcher_t* dispatcher) {
                  isolated_archivist_service_dir_.Connect(
                      fuchsia::logger::LogSink::Name_, std::move(channel));
                }),
            fuchsia::logger::LogSink::Name_),
        ZX_OK);

    return create_params;
  }

  void LoadLogTestPage() {
    EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
        navigation_controller_.get(), fuchsia::web::LoadUrlParams(),
        embedded_test_server_.GetURL(std::string("/") + kLogTestPageFileName)
            .spec()));
  }

  fuchsia::sys::ComponentControllerPtr archivist_controller_;
  sys::ServiceDirectory isolated_archivist_service_dir_;

  fuchsia::logger::LogPtr logger_;
};

// Verifies that calling messages from console.debug() calls go to the Fuchsia
// system log when the script log level is set to DEBUG.
TEST_F(WebEngineIntegrationLoggingTest, SetJavaScriptLogLevel_DEBUG) {
  base::SimpleTestLogListener log_listener;
  log_listener.ListenToLog(logger_.get(), nullptr);

  // Create the Context & Frame with all log severities enabled.
  fuchsia::web::CreateFrameParams frame_params;
  frame_params.set_debug_name(kFrameLogTag);
  CreateContextAndFrameWithParams(ContextParamsWithIsolatedLogSink(),
                                  std::move(frame_params));
  frame_->SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel::DEBUG);

  // Re-connect to the NavigationController, to ensure that the new log level
  // has been applied before the LoadUrl() request is processed.
  navigation_controller_ = nullptr;
  navigation_listener_ = nullptr;
  AddNavigationControllerAndListenerToFrame(&frame_);

  // Navigate to the test page, which will emit console logging.
  LoadLogTestPage();
  navigation_listener_->RunUntilTitleEquals("ended");

  // Run until the message passed to console.debug() is received.
  base::Optional<fuchsia::logger::LogMessage> logged_message =
      log_listener.RunUntilMessageReceived(kLogTestPageDebugMessage);

  ASSERT_TRUE(logged_message.has_value());

  // console.debug() should map to Fuchsia's DEBUG log severity.
  EXPECT_EQ(logged_message->severity,
            static_cast<int32_t>(fuchsia::logger::LogLevelFilter::DEBUG));

  // Verify that the Frame's |debug_name| is amongst the log message tags.
  EXPECT_FALSE(logged_message->tags.empty());
  EXPECT_TRUE(base::Contains(logged_message->tags, kFrameLogTag));

  // Verify that the message is formatted as expected.
  EXPECT_EQ(NormalizeConsoleLogMessage(logged_message->msg),
            std::string("http://127.0.0.1:") + kNormalizedPortNumber +
                "/console_logging.html:8 : This is a debug() message.");
}
