// Copyright 2019 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 <fuchsia/ui/app/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fdio/spawn.h>
#include <lib/fit/function.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <lib/zx/clock.h>
#include <lib/zx/time.h>
#include <zircon/status.h>

#include <iomanip>
#include <map>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include "src/chromium/web_runner_tests/mock_get.h"
#include "src/chromium/web_runner_tests/test_server.h"
#include "src/chromium/web_runner_tests/web_context.h"
#include "src/lib/fsl/vmo/vector.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/lib/ui/base_view/embedded_view_utils.h"
#include "src/ui/testing/views/embedder_view.h"

namespace {

// Max time to wait in failure cases before bailing.
constexpr zx::duration kTimeout = zx::sec(15);
constexpr uint32_t kBlankColor = 0x00000000;

constexpr zx::duration kTestTimeout = zx::sec(60);

std::map<uint32_t, size_t> Histogram(const fuchsia::ui::scenic::ScreenshotData& screenshot) {
  EXPECT_GT(screenshot.info.width, 0u);
  EXPECT_GT(screenshot.info.height, 0u);

  std::vector<uint8_t> data;
  EXPECT_TRUE(fsl::VectorFromVmo(screenshot.data, &data)) << "Failed to read screenshot";

  std::map<uint32_t, size_t> histogram;
  const uint32_t* bitmap = reinterpret_cast<const uint32_t*>(data.data());
  const size_t size = screenshot.info.width * screenshot.info.height;
  EXPECT_EQ(size * sizeof(uint32_t), data.size());
  for (size_t i = 0; i < size; ++i) {
    ++histogram[bitmap[i]];
  }

  return histogram;
}

// Invokes the input tool for input injection.
// See src/ui/tools/input/README.md or `input --help` for usage details.
// Commands used here:
//  * tap <x> <y> (scaled out of 1000)
// TODO(fxbug.dev/24462): Expose as a FIDL service.
void Input(std::vector<const char*> args) {
  // start with proc name, end with nullptr
  args.insert(args.begin(), "input");
  args.push_back(nullptr);

  zx_handle_t proc;
  zx_status_t status =
      fdio_spawn(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, "/bin/input", args.data(), &proc);
  FX_CHECK(status == ZX_OK) << "fdio_spawn: " << zx_status_get_string(status);

  status = zx_object_wait_one(proc, ZX_PROCESS_TERMINATED,
                              (zx::clock::get_monotonic() + kTimeout).get(), nullptr);
  FX_CHECK(status == ZX_OK) << "zx_object_wait_one: " << zx_status_get_string(status);

  zx_info_process_t info;
  status = zx_object_get_info(proc, ZX_INFO_PROCESS, &info, sizeof(info), nullptr, nullptr);
  FX_CHECK(status == ZX_OK) << "zx_object_get_info: " << zx_status_get_string(status);
  FX_CHECK(info.return_code == 0) << info.return_code;
}

// Base fixture for pixel tests, containing Scenic and presentation setup, and
// screenshot utilities.
class PixelTest : public gtest::RealLoopFixture {
 protected:
  PixelTest() : context_(sys::ComponentContext::CreateAndServeOutgoingDirectory()) {
    scenic_ = context_->svc()->Connect<fuchsia::ui::scenic::Scenic>();
    scenic_.set_error_handler([](zx_status_t status) {
      FAIL() << "Lost connection to Scenic: " << zx_status_get_string(status);
    });

    // TODO(fxbug.dev/40933)
    //
    // These tests can flake when a screenshot captures a frame from the previous test, which can
    // advance the test logic early. This is a temporary solution that waits for a blank on setup.
    // Better solutions include hermetic Scenic (using src/ui/scenic/lib/gfx/tests/pixel_test.h) or
    // refactoring to use view state events (probably the best solution; greatly improves
    // determinism at the expense of added harness complexity).
    //
    // WebRunnerPixelTest.Static below is factored to use view state events, but the others are not.
    FX_CHECK(WaitForBlank());
  }

  sys::ComponentContext* context() { return context_.get(); }
  fuchsia::ui::scenic::Scenic* scenic() { return scenic_.get(); }

  // Gets a view token for presentation by |RootPresenter|. See also
  // garnet/examples/ui/hello_base_view
  fuchsia::ui::views::ViewToken CreatePresentationViewToken() {
    auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();

    auto presenter = context_->svc()->Connect<fuchsia::ui::policy::Presenter>();
    presenter.set_error_handler(
        [](zx_status_t status) { FAIL() << "presenter: " << zx_status_get_string(status); });
    presenter->PresentOrReplaceView(std::move(view_holder_token), nullptr);

    return std::move(view_token);
  }

  bool ScreenshotUntil(fit::function<bool(fuchsia::ui::scenic::ScreenshotData, bool)> condition,
                       zx::duration timeout = kTimeout) {
    zx::time start = zx::clock::get_monotonic();
    while (zx::clock::get_monotonic() - start <= timeout) {
      fuchsia::ui::scenic::ScreenshotData screenshot;
      bool ok;
      scenic_->TakeScreenshot(
          [this, &screenshot, &ok](fuchsia::ui::scenic::ScreenshotData screenshot_in, bool status) {
            ok = status;
            screenshot = std::move(screenshot_in);
            QuitLoop();
          });

      if (!RunLoopWithTimeout(timeout) && condition(std::move(screenshot), ok)) {
        return true;
      }
    }

    return false;
  }

  // Blank can manifest as invalid screenshots or blackness.
  // TODO(fxbug.dev/40933): remove
  bool WaitForBlank() {
    return ScreenshotUntil([](fuchsia::ui::scenic::ScreenshotData screenshot, bool status) {
      return !status || Histogram(screenshot)[kBlankColor] > 0u;
    });
  }

  void ExpectSolidColor(uint32_t argb) {
    std::map<uint32_t, size_t> histogram;

    FX_LOGS(INFO) << "Looking for color " << std::hex << argb << ".";
    EXPECT_TRUE(ScreenshotUntil(
        [argb, &histogram](fuchsia::ui::scenic::ScreenshotData screenshot, bool status) {
          if (!status)
            return false;

          histogram = Histogram(screenshot);
          FX_LOGS(INFO) << "Looking for color " << std::hex << argb << ": found " << std::dec
                        << histogram[argb] << " px.";
          return histogram[argb] > 0u;
        }));

    histogram.erase(argb);
    EXPECT_EQ((std::map<uint32_t, size_t>){}, histogram) << "Unexpected colors";
  }

  void ExpectPrimaryColor(uint32_t color) {
    std::multimap<size_t, uint32_t> inverse_histogram;

    FX_LOGS(INFO) << "Looking for color " << std::hex << color;
    EXPECT_TRUE(ScreenshotUntil([color, &inverse_histogram](
                                    fuchsia::ui::scenic::ScreenshotData screenshot, bool status) {
      if (!status)
        return false;

      std::map<uint32_t, size_t> histogram = Histogram(screenshot);
      FX_LOGS(INFO) << histogram[color] << " px";

      inverse_histogram.clear();
      for (const auto entry : histogram) {
        inverse_histogram.emplace(entry.second, entry.first);
      }

      return (--inverse_histogram.end())->second == color;
    })) << "Primary color: "
        << std::hex << (--inverse_histogram.end())->second;
  }

 private:
  std::unique_ptr<sys::ComponentContext> context_;
  fuchsia::sys::ComponentControllerPtr runner_ctrl_;
  fuchsia::ui::scenic::ScenicPtr scenic_;
};

using WebRunnerPixelTest = PixelTest;

// Loads a static page with a solid color via the component framework and
// verifies that the color is the only color onscreen.
TEST_F(WebRunnerPixelTest, Static) {
  static constexpr uint32_t kTargetColor = 0xffff00ff;

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

  // Chromium and the Fuchsia network package loader both send us requests. This
  // may go away after fxbug.dev/17641; although the race seems to be in Modular, the
  // fix may remove the unnecessary net request in component framework.
  auto serve = server.ServeAsync([&server] {
    while (server.Accept()) {
      web_runner_tests::MockHttpGetResponse(&server, "static.html");
    }
  });

  fuchsia::sys::ComponentControllerPtr controller;
  fuchsia::sys::LauncherPtr launcher;
  context()->svc()->Connect(launcher.NewRequest());

  auto info = scenic::LaunchComponentAndCreateView(
      launcher, fxl::StringPrintf("http://localhost:%d/static.html", server.port()), {});

  info.controller.events().OnTerminated = [](int64_t code, fuchsia::sys::TerminationReason reason) {
    FAIL();
  };

  // Present the view.
  scenic::EmbedderView embedder_view({
      .session_and_listener_request = scenic::CreateScenicSessionPtrAndListenerRequest(scenic()),
      .view_token = CreatePresentationViewToken(),
  });

  embedder_view.EmbedView(
      std::move(info),
      /*view_state_changed_callback=*/[this](fuchsia::ui::gfx::ViewState view_state) {
        EXPECT_TRUE(view_state.is_rendering);
        QuitLoop();
      });

  // Wait to get a signal that the view is being rendered.
  EXPECT_FALSE(RunLoopWithTimeout(kTestTimeout))
      << "Timed out waiting for a ViewStateChanged event.";

  ExpectSolidColor(kTargetColor);
}

// This fixture uses fuchsia.web FIDL services to interact with the WebEngine.
class WebPixelTest : public PixelTest {
 protected:
  WebPixelTest()
      : web_context_(context(), fuchsia::web::ContextFeatureFlags::VULKAN |
                                    fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER),
        embedder_view_({
            .session_and_listener_request =
                scenic::CreateScenicSessionPtrAndListenerRequest(scenic()),
            .view_token = CreatePresentationViewToken(),
        }) {
    auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();

    web_context_.web_frame()->CreateView(std::move(view_token));

    scenic::EmbeddedViewInfo embedded_view_info;
    embedded_view_info.view_holder_token = std::move(view_holder_token);
    embedder_view_.EmbedView(
        std::move(embedded_view_info),
        /*view_state_changed_callback=*/[this](fuchsia::ui::gfx::ViewState view_state) {
          EXPECT_TRUE(view_state.is_rendering);
          QuitLoop();
        });

    // Wait to get a signal that the view is being rendered.
    EXPECT_FALSE(RunLoopWithTimeout(kTestTimeout))
        << "Timed out waiting for a ViewStateChanged event.";
  }

  WebContext* web_context() { return &web_context_; }

 private:
  WebContext web_context_;
  scenic::EmbedderView embedder_view_;
};

// Loads a static page with a solid color via fuchsia.web interfaces and
// verifies that the color is the only color onscreen.
TEST_F(WebPixelTest, Static) {
  static constexpr uint32_t kTargetColor = 0xffff00ff;

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

  auto serve = server.ServeAsync([&server] {
    FX_LOGS(INFO) << "Waiting for HTTP request from Chromium";
    ASSERT_TRUE(server.Accept()) << "Did not receive HTTP request from Chromium";
    web_runner_tests::MockHttpGetResponse(&server, "static.html");
  });

  web_context()->Navigate(fxl::StringPrintf("http://localhost:%d/static.html", server.port()));
  ExpectSolidColor(kTargetColor);
}

// Loads a dynamic page that starts with a Fuchsia background. This test verifies the initial color,
// taps on the view, and verifies that the color changed.
TEST_F(WebPixelTest, Dynamic) {
  static constexpr uint32_t kBeforeColor = 0xffff00ff;
  static constexpr uint32_t kAfterColor = 0xff40e0d0;

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

  auto serve = server.ServeAsync([&server] {
    ASSERT_TRUE(server.Accept());
    web_runner_tests::MockHttpGetResponse(&server, "dynamic.html");
  });

  web_context()->Navigate(fxl::StringPrintf("http://localhost:%d/dynamic.html", server.port()));

  ExpectPrimaryColor(kBeforeColor);
  Input({"tap", "500", "125"});  // centered in top quarter of screen
  ExpectPrimaryColor(kAfterColor);
}

// Loads a static page with a video.
TEST_F(WebPixelTest, Video) {
  web_runner_tests::TestServer server;
  FX_CHECK(server.FindAndBindPort());

  auto serve = server.ServeAsync([&server] {
    FX_LOGS(INFO) << "Waiting for HTTP request from Chromium";
    ASSERT_TRUE(server.Accept()) << "Did not receive HTTP request from Chromium";
    web_runner_tests::MockHttpGetResponse(&server, "video.html");
    web_runner_tests::MockHttpGetResponse(&server, "blackwhite_yuv420p.webm");
  });

  web_context()->Navigate(fxl::StringPrintf("http://localhost:%d/video.html", server.port()));

  static constexpr uint32_t kBlackColor = 0xff010001;
  static constexpr uint32_t kWhiteColor = 0xfffffeff;
  static constexpr uint32_t kVideoBackgroundColor = 0xffff00ff;
  std::map<uint32_t, size_t> histogram;
  EXPECT_TRUE(
      ScreenshotUntil([&histogram](fuchsia::ui::scenic::ScreenshotData screenshot, bool status) {
        if (!status)
          return false;

        histogram = Histogram(screenshot);
        return histogram[kBlackColor] > 0u;
      }));
  // We expect 240x240 <video> with black and white quadrants with grey on top. <video> background
  // color should not be visible at all.
  EXPECT_GT(histogram[kBlackColor], 10000u) << "Unexpected colors";
  EXPECT_GT(histogram[kWhiteColor], 10000u) << "Unexpected colors";
  EXPECT_EQ(histogram[kVideoBackgroundColor], 0u) << "Unexpected colors";
}

}  // namespace
