// Copyright 2013 The Flutter 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 "flutter/fml/synchronization/waitable_event.h"
#include "flutter/testing/testing.h"
#include "impeller/toolkit/android/choreographer.h"
#include "impeller/toolkit/android/hardware_buffer.h"
#include "impeller/toolkit/android/proc_table.h"
#include "impeller/toolkit/android/surface_control.h"
#include "impeller/toolkit/android/surface_transaction.h"

namespace impeller::android::testing {

#define DISABLE_ANDROID_PROC(name)                 \
  struct Disable##name {                           \
    Disable##name() {                              \
      real_proc = GetMutableProcTable().name.proc; \
      GetMutableProcTable().name.proc = nullptr;   \
    }                                              \
    ~Disable##name() {                             \
      GetMutableProcTable().name.proc = real_proc; \
    }                                              \
    decltype(name)* real_proc;                     \
  } disable##name;

TEST(ToolkitAndroidTest, CanCreateProcTable) {
  ProcTable proc_table;
  ASSERT_TRUE(proc_table.IsValid());
}

TEST(ToolkitAndroidTest, GuardsAgainstZeroSizedDescriptors) {
  auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({0, 0});
  ASSERT_GT(desc.size.width, 0u);
  ASSERT_GT(desc.size.height, 0u);
}

TEST(ToolkitAndroidTest, CanCreateHardwareBuffer) {
  if (!HardwareBuffer::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Hardware buffers are not supported on this platform.";
  }
  ASSERT_TRUE(HardwareBuffer::IsAvailableOnPlatform());
  auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({100, 100});
  ASSERT_TRUE(desc.IsAllocatable());
  HardwareBuffer buffer(desc);
  ASSERT_TRUE(buffer.IsValid());
}

TEST(ToolkitAndroidTest, CanGetHardwareBufferIDs) {
  if (!HardwareBuffer::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Hardware buffers are not supported on this platform.";
  }
  ASSERT_TRUE(HardwareBuffer::IsAvailableOnPlatform());
  if (!GetProcTable().AHardwareBuffer_getId.IsAvailable()) {
    GTEST_SKIP() << "Hardware buffer IDs are not available on this platform.";
  }
  auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({100, 100});
  ASSERT_TRUE(desc.IsAllocatable());
  HardwareBuffer buffer(desc);
  ASSERT_TRUE(buffer.IsValid());
  ASSERT_TRUE(buffer.GetSystemUniqueID().has_value());
}

TEST(ToolkitAndroidTest, HardwareBufferNullIDIfAPIUnavailable) {
  DISABLE_ANDROID_PROC(AHardwareBuffer_getId);
  ASSERT_FALSE(HardwareBuffer::GetSystemUniqueID(nullptr).has_value());
}

TEST(ToolkitAndroidTest, CanDescribeHardwareBufferHandles) {
  if (!HardwareBuffer::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Hardware buffers are not supported on this platform.";
  }
  ASSERT_TRUE(HardwareBuffer::IsAvailableOnPlatform());
  auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({100, 100});
  ASSERT_TRUE(desc.IsAllocatable());
  HardwareBuffer buffer(desc);
  ASSERT_TRUE(buffer.IsValid());
  auto a_desc = HardwareBuffer::Describe(buffer.GetHandle());
  ASSERT_TRUE(a_desc.has_value());
  ASSERT_EQ(a_desc->width, 100u);   // NOLINT
  ASSERT_EQ(a_desc->height, 100u);  // NOLINT
}

TEST(ToolkitAndroidTest, CanApplySurfaceTransaction) {
  if (!SurfaceTransaction::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Surface controls are not supported on this platform.";
  }
  ASSERT_TRUE(SurfaceTransaction::IsAvailableOnPlatform());
  SurfaceTransaction transaction;
  ASSERT_TRUE(transaction.IsValid());
  fml::AutoResetWaitableEvent event;
  ASSERT_TRUE(transaction.Apply([&event]() { event.Signal(); }));
  event.Wait();
}

TEST(ToolkitAndroidTest, SurfacControlsAreAvailable) {
  if (!SurfaceControl::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Surface controls are not supported on this platform.";
  }
  ASSERT_TRUE(SurfaceControl::IsAvailableOnPlatform());
}

TEST(ToolkitAndroidTest, ChoreographerIsAvailable) {
  if (!Choreographer::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Choreographer is not supported on this platform.";
  }
  ASSERT_TRUE(Choreographer::IsAvailableOnPlatform());
}

TEST(ToolkitAndroidTest, CanPostAndNotWaitForFrameCallbacks) {
  if (!Choreographer::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Choreographer is not supported on this platform.";
  }
  const auto& choreographer = Choreographer::GetInstance();
  ASSERT_TRUE(choreographer.IsValid());
  ASSERT_TRUE(choreographer.PostFrameCallback([](auto) {}));
}

TEST(ToolkitAndroidTest, CanPostAndWaitForFrameCallbacks) {
  if (!Choreographer::IsAvailableOnPlatform()) {
    GTEST_SKIP() << "Choreographer is not supported on this platform.";
  }
  if ((true)) {
    GTEST_SKIP()
        << "Disabled till the test harness is in an Android activity. "
           "Running it without one will hang because the choreographer "
           "frame callback will never execute.";
  }
  const auto& choreographer = Choreographer::GetInstance();
  ASSERT_TRUE(choreographer.IsValid());
  fml::AutoResetWaitableEvent event;
  ASSERT_TRUE(choreographer.PostFrameCallback(
      [&event](auto point) { event.Signal(); }));
  event.Wait();
}

}  // namespace impeller::android::testing
