// 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/ui/composition/cpp/fidl.h>
#include <fuchsia/ui/test/input/cpp/fidl.h>

#include <fstream>
#include <iostream>
#include <string>
#include <unordered_set>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <rapidjson/document.h>

#include "lib/zx/clock.h"
#include "lib/zx/time.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/virtualization/tests/lib/enclosed_guest.h"
#include "src/virtualization/tests/lib/guest_test.h"
#include "src/virtualization/tests/lib/periodic_logger.h"

namespace {

using testing::AllOf;
using testing::Ge;
using testing::Le;

// Set to "true" to save screenshots to disk.
constexpr bool kSaveScreenshot = false;
constexpr char kScreenshotSaveLocation[] = "/tmp/screenshot-%s.raw";

constexpr char kVirtioGpuTestUtil[] = "virtio_gpu_test_util";

// How long to run tests before giving up and failing.
constexpr zx::duration kGpuTestTimeout = zx::sec(15);

struct Screenshot {
  // Height and width of the image, in pixels.
  int height;
  int width;

  // Raw pixel data, 4 bytes per pixel, stored in RGBO format, one row at
  // a time.
  std::vector<std::byte> data;
};

template <typename T>
class VirtioGpuTest : public GuestTest<T> {
 protected:
  void SetUp() override {
    GuestTest<T>::SetUp();
    screenshot_ =
        this->GetEnclosedGuest().template ConnectToService<fuchsia::ui::composition::Screenshot>();
    display_info_ = this->GetEnclosedGuest().WaitForDisplay();
  }

  zx_status_t CaptureScreenshot(Screenshot* screenshot) {
    fuchsia::ui::composition::ScreenshotTakeRequest request;
    request.set_format(fuchsia::ui::composition::ScreenshotFormat::BGRA_RAW);
    std::optional<zx_status_t> screenshot_result;
    screenshot_->Take(std::move(request), [screenshot, &screenshot_result](auto response) {
      screenshot->width = response.size().width;
      screenshot->height = response.size().height;

      size_t size = screenshot->width * screenshot->height * 4;
      screenshot->data.reserve(size);
      zx_status_t status = response.vmo().read(screenshot->data.data(), 0, size);
      if (status != ZX_OK) {
        screenshot_result = status;
      }
      screenshot_result = ZX_OK;
    });

    if (!this->RunLoopUntil([&] { return screenshot_result.has_value(); },
                            zx::deadline_after(kGpuTestTimeout))) {
      return ZX_ERR_TIMED_OUT;
    }
    return *screenshot_result;
  }

  EnclosedGuest::DisplayInfo display_info_;
  fuchsia::ui::composition::ScreenshotPtr screenshot_;
};

using GuestTypes = ::testing::Types<DebianGpuEnclosedGuest, ZirconGpuEnclosedGuest>;
TYPED_TEST_SUITE(VirtioGpuTest, GuestTypes, GuestTestNameGenerator);

// Poll |condition| using exponential backoff until it returns true, or
// a timeout has passed.
//
// Returns true iff |condition| returned true before the deadline.
template <typename C>
bool PollCondition(C condition, zx::duration timeout, PeriodicLogger logger) {
  const zx::time deadline = zx::deadline_after(timeout);
  zx::duration wait_time = zx::usec(1);

  do {
    // Have we succeeded?
    if (condition()) {
      return true;
    }

    // Sleep, with exponential backoff.
    zx::nanosleep(zx::deadline_after(wait_time));
    wait_time = std::max(wait_time * 2, zx::sec(1));
  } while (zx::clock::get_monotonic() < deadline);

  // Perform one final check.
  return condition();
}

// compiled in.
void SaveScreenshot(const std::string& prefix, const Screenshot& screenshot) {
  if (kSaveScreenshot) {
    std::string filename = fxl::StringPrintf(kScreenshotSaveLocation, prefix.c_str());
    FX_LOGS(INFO) << fxl::StringPrintf(
        "Saving screenshot to '%s'. Copy from the device using:\n"
        "#  fx scp \"[$(fx get-device-addr)]\":%s data.raw\n"
        "Display it using ImageMagick using one of the following commands.\n"
        "Linux guests:\n"
        "#  display -size %dx%d -depth 8 RGBO:data.raw\n"
        "Fuchsia guests:\n"
        "#  display -size %dx%d -depth 8 RGBA:data.raw\n",
        filename.c_str(), filename.c_str(), screenshot.width, screenshot.height, screenshot.width,
        screenshot.height);
    std::ofstream output;
    output.open(filename);
    output.write(reinterpret_cast<const char*>(screenshot.data.data()), screenshot.data.size());
    output.close();
  }
}

// Determine if the given screenshot has at least 1 non-black pixel.
//
// We assume the data format is RGBA or RGBO, where each pixel is four bytes:
// [red] [green] [blue] [alpha/opacity]
bool HasNonBlackPixel(const Screenshot& screenshot) {
  FX_CHECK(screenshot.data.size() % 4 == 0);
  for (size_t i = 0; i < screenshot.data.size(); i += 4) {
    std::byte r = screenshot.data[i + 0];
    std::byte g = screenshot.data[i + 1];
    std::byte b = screenshot.data[i + 2];
    if (r != std::byte(0) || g != std::byte(0) || b != std::byte(0)) {
      return true;
    }
  }
  return false;
}

// Count number of unique colours in the screenshot.
//
// For this test, we treat data as having different alpha values as different
// colours.
int NumberOfUniqueColors(const Screenshot& screenshot) {
  FX_CHECK(screenshot.data.size() % 4 == 0);
  std::unordered_set<uint32_t> seen_colors;
  int unique_colors = 0;
  for (size_t i = 0; i < screenshot.data.size(); i += 4) {
    uint32_t color = *reinterpret_cast<const uint32_t*>(&screenshot.data[i]);
    auto [_, new_color] = seen_colors.insert(color);
    if (new_color) {
      unique_colors++;
    }
  }
  return unique_colors;
}

bool ScreenshotsSame(const Screenshot& a, const Screenshot& b) {
  if (a.height != b.height || a.width != b.width) {
    return false;
  }
  return a.data == b.data;
}

TYPED_TEST(VirtioGpuTest, DetectDisplay) {
  // TODO(https://fxbug.dev/42080718): Fix and re-enable this test on zircon.
  if (this->GetGuestKernel() == GuestKernel::ZIRCON) {
    GTEST_SKIP();
  }

  std::string result;
  ASSERT_EQ(this->RunUtil(kVirtioGpuTestUtil, {"detect"}, &result), ZX_OK);

  // Expect that a single display was detected, and the geometry should match that of the created
  // view.
  //
  // The output is expected to look like:
  // {
  //   "displays": [
  //     {
  //       "width": <width>,
  //       "height": <height>
  //     }
  //    ]
  // }
  //
  // The width and height are expected to also match the size of the backing Fuchsia view.
  rapidjson::Document document;
  document.Parse(result);
  EXPECT_TRUE(document.IsObject());
  EXPECT_TRUE(document.HasMember("displays"));
  EXPECT_TRUE(document["displays"].IsArray());

  const auto& displays = document["displays"].GetArray();
  EXPECT_EQ(1u, displays.Size());
  EXPECT_TRUE(displays[0].IsObject());

  const auto& display = displays[0];
  EXPECT_TRUE(display.HasMember("width") && display["width"].IsUint());
  EXPECT_TRUE(display.HasMember("height") && display["height"].IsUint());
  EXPECT_EQ(this->display_info_.width, display["width"].GetUint());
  EXPECT_EQ(this->display_info_.height, display["height"].GetUint());
}

TYPED_TEST(VirtioGpuTest, ScreenNotBlack) {
  // TODO(https://fxbug.dev/42053853): Revive the this test.
  GTEST_SKIP();

  // Take a screenshot.
  Screenshot screenshot;
  zx_status_t status = this->CaptureScreenshot(&screenshot);
  ASSERT_EQ(status, ZX_OK) << "Error capturing screenshot.";
  SaveScreenshot("screen-not-black", screenshot);

  // Ensure that at least 1 pixel is not black.
  EXPECT_TRUE(HasNonBlackPixel(screenshot)) << "All pixels in the captured screenshot were black.";
}

TYPED_TEST(VirtioGpuTest, ScreenDataLooksValid) {
  // TODO(https://fxbug.dev/42053853): Revive the this test.
  GTEST_SKIP();

  // Take a screenshot.
  Screenshot screenshot;
  zx_status_t status = this->CaptureScreenshot(&screenshot);
  ASSERT_EQ(status, ZX_OK) << "Error capturing screenshot.";
  SaveScreenshot("unique-colors", screenshot);

  // Ensure that we have at least 2 distinct colours, but no more than 16. The
  // idea here is that we want to ensure the screen is showing _something_
  // (white text on a black background), but not complete garbage
  // (uninitialised memory, for example).
  //
  // Both Zircon and Linux guests have a simple console on bootup, so ensuring
  // that we only have a few unique colours lets us approximate this.
  //
  // If you've just added a beautiful rainbow to Fuchsia's console and now
  // this test is failing, I'm really, truly sorry.
  EXPECT_THAT(NumberOfUniqueColors(screenshot), AllOf(Ge(2), Le(16)))
      << "The screenshot had a suspicious number of colours, suggesting it "
         "may not actually be real screen content.";
}

TYPED_TEST(VirtioGpuTest, TextInputChangesConsole) {
  // TODO(https://fxbug.dev/42053853): Revive the this test.
  GTEST_SKIP();

  // Take a screenshot.
  Screenshot screenshot1;
  zx_status_t status = this->CaptureScreenshot(&screenshot1);
  ASSERT_EQ(status, ZX_OK) << "Error capturing screenshot.";
  SaveScreenshot("input-state1", screenshot1);

  // Type a key, which should update the display.
  auto input_registry =
      this->GetEnclosedGuest().template ConnectToService<fuchsia::ui::test::input::Registry>();
  fuchsia::ui::test::input::KeyboardPtr keyboard;
  bool keyboard_registered = false;
  fuchsia::ui::test::input::RegistryRegisterKeyboardRequest request;
  request.set_device(keyboard.NewRequest());
  input_registry->RegisterKeyboard(std::move(request), [&]() { keyboard_registered = true; });
  this->RunLoopUntil([&] { return keyboard_registered; }, zx::deadline_after(kGpuTestTimeout));
  bool input_injected = false;
  fuchsia::ui::test::input::KeyboardSimulateUsAsciiTextEntryRequest text_request;
  text_request.set_text("a");
  keyboard->SimulateUsAsciiTextEntry(std::move(text_request),
                                     [&input_injected]() { input_injected = true; });
  this->RunLoopUntil([&] { return input_injected; }, zx::deadline_after(kGpuTestTimeout));

  // Take another screenshot.
  //
  // We keep polling to handle any delay in propagating input to output.
  bool success = PollCondition(
      [&screenshot1]() -> bool {
        // Wait for the screen to change.
        Screenshot screenshot2;
        SaveScreenshot("input-state2", screenshot2);
        return !ScreenshotsSame(screenshot1, screenshot2);
      },
      /*timeout=*/kGpuTestTimeout, PeriodicLogger("Waiting for change in console", zx::sec(1)));

  // Ensure something changed.
  EXPECT_TRUE(success)
      << "Expected keystroke events to change console output, but nothing changed.";
}

}  // namespace
